小白_图论1 基础题

小白_图论1    

1、UVA 10034   最小生成树,水,墨水连点。

2、UVA 10048   floyd,找最小的可行径上的最大边,水,忍受噪音。

3、UVA 10397   最小生成树,题意:架设电缆,但有的点已经相连。  总结:已经相连的点,先连通或者直接标为0。Prim直接过了,但Kruskal一直RE,不知道哪错了。

4、UVA 10369   最小生成树,题意:p个哨点相连,有卫星通道,求最大dis。  总结:题意有点纠结,s个卫星只能有s-1个卫星通道。所以就是第p-s条边。

5、UVA 658     最短路,题意:好迷,查bug,有m个补丁,每个补丁两个字符串s1,s2,s1表示可以用这个补丁的条件,s2表示用后变化。  总结:状态表示成点,但这里好纠结。 不会

6、UVA 10099   floyd,找最大的可行径上的最小边,G[i][j]=max(G[i][j], min(G[i][k],G[k][j])),水,旅游团带人。

7、

8、

9、

 

思路总结:

/*
Floyd  思路总结:
有点像dp,对于G[i][j],介入一个点k(如果存在G[i][k],G[k][j]),
然后在G[i][j]、G[i][k]、G[k][j]之间取最优值。
但Floyd复杂度很高,只能处理范围小的情况
*/
int n,m,G[N][N];
void Floyd()
{
    FF(k,1,n) FF(i,1,n) FF(j,1,n) {     // k要放在最外层
        G[i][j]=max(G[i][j], min(G[i][k],G[k][j]));
    }
}
Floyd
/*
Kruskal 思路总结
然后把所有边按权值排序,遍历。如果这条边相连两点不是一个连通分量,
就利用并查集,把这两点并成一个连通分量。
*/
struct Edge
{
    int u,v;
    double val;
    friend bool operator < (const Edge &a, const Edge &b) {
        return b.val>a.val;
    }
}edge[N*N];
int n,m,x[N],y[N];
int tot,father[N];

double Dis(int i,int j)
{
    return sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) );
}
void Addedge(int u,int v,double len)
{
    edge[tot].u=u, edge[tot].v=v, edge [tot++].val=len;
}
int Find(int c)
{
    int p=c,i=c,j;
    while(father[p]!=p)  p=father[p];
    while(father[i]!=p) {
        j=father[i], father[i]=p, i=j;
    }
    return p;
}
bool Unite(int u,int v)
{
    int fau=Find(u), fav=Find(v);
    if(fau!=fav) { father[fav]=fau; return true; }
    return false;
}
double Kruskal()
{
    double sum=0;
    int num=0;
    sort(edge,edge+tot);
    F(i,0,tot) {
        if(num>=n-1) break;
        if(Unite(edge[i].u,edge[i].v)) sum+=edge[i].val, num++;
    }
    return sum;
}
Kruskal
/*
Prim 思路总结:
n个点分为两个集合U、R,U为已取的点,R为未取的点,先任意取一个点放入U中。
取距离最小的U中点可以到达的R中点,放入U中,如此n-1遍。
*/
int vis[N],G[N][N];
double Prim()
{
    double sum=0;
    vis[1]=1;
    FF(i,2,n) {   //循环n-1次即可
        double minn=M;
        int mi,mj;
        FF(i,1,n) if(vis[i]==1) {  //每次找出未取的距离最小的点
            FF(j,1,n) if(vis[j]==0) {
                if(minn>G[i][j]) {
                    minn=G[i][j], mi=i, mj=j;
                }
            }
        }
        sum+=G[mi][mj], vis[mj]=1;
    }
    return sum;
}
Prim
posted @ 2017-01-04 15:12  v9fly  阅读(147)  评论(0编辑  收藏  举报