UVALive 6807 Túnel de Rata (最大生成树)

来源:互联网 发布:如何更换网络节点 编辑:程序博客网 时间:2024/06/06 06:37

大体题意:

一个老鼠从A点出发,经过一个环回到起点,他可能走到任意地点, 让你在一些边上放摄像头,使得无论老鼠怎么走,总有一个摄像头能看到老鼠!

摄像头的成本是这条边的权值!

思路:

既然他可以走到任意点,所以每个点都要能监视到,而且权值最小,而且有环,先求一个最大生成树!因为有环,旁边的点一定可以监视到这个最大生成树,这样保证了,可以监视整个图,也保证了权值和不是最大,剩下的在非最大生成树中找到一个最大点作为第二个输出即可!

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100000 + 10;struct Edge{    int x,y,w;    bool operator < (const Edge& rhs) const {        return w > rhs.w;    }}p[maxn];int fa[maxn],vis[maxn];int find(int x){    return x == fa[x] ? fa[x] : fa[x] = find(fa[x]);}int main(){    int T,kase = 0;    scanf("%d",&T);    while(T--){        memset(vis,0,sizeof vis);        int u, v, w;        int n, m;        scanf("%d %d",&n,&m);        for (int i = 0; i < m; ++i){            scanf("%d %d %d",&u,&v,&w);            p[i].x = u;            p[i].y = v;            p[i].w = w;        }        sort(p,p+m);        for (int i = 0; i <= n; ++i)fa[i] = i;        int cnt = n;        for (int i = 0; i < m; ++i){            int xx = find(p[i].x);            int yy = find(p[i].y);            if (xx != yy){                vis[i] = 1;                fa[yy] = xx;                --cnt;            }            if (cnt == 1)break;        }        int Max = -1;        int sum = 0;        for (int i = 0; i < m; ++i){            if (vis[i])continue;            Max = max(Max,p[i].w);            sum += p[i].w;        }        printf("Case #%d: %d %d\n",++kase,sum,Max);    }    return 0;}


0 0
原创粉丝点击