UVa10600 ACM Contest and Blackout(最小和次小生成树)

来源:互联网 发布:sql语句编写 编辑:程序博客网 时间:2024/06/18 12:44

简介:
最小生成树和次小生成树

分析:
当图变成了一棵树(纠结的生成树)

//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int INF=0x33333333;int maxline[103][103];struct node1{    int x,y,v;};node1 e[20005];struct node2{    int x,y,v,nxt;}; node2 way[203];int st[103],tot,fa[103],n,m;bool p[103],pw[103];bool operator < (const node1 &a,const node1 &b){return a.v<b.v;}void add(int u,int w,int z){    tot++;    way[tot].x=u;way[tot].y=w;way[tot].v=z;way[tot].nxt=st[u];st[u]=tot;    tot++;    way[tot].x=w;way[tot].y=u;way[tot].v=z;way[tot].nxt=st[w];st[w]=tot;}int find(int x){    if (fa[x]!=x) fa[x]=find(fa[x]);    return fa[x];}void unionn(int f1,int f2){fa[f1]=f2;}int Kruskal(){    sort(e+1,e+1+m);    int cnt=0,ans=0;    for (int i=1;i<=n;i++) fa[i]=i;    for (int i=1;i<=m;i++)    {        int f1=find(e[i].x);        int f2=find(e[i].y);        if (f1!=f2)        {            cnt++; ans+=e[i].v;            unionn(f1,f2);            add(e[i].x,e[i].y,e[i].v);            pw[i]=0;        }        if (cnt==n-1) break;    }    return ans;}void dfs(int now,int f,int dis)                      //最小瓶颈路的最大边圈 {    if (f!=-1)    for (int j=1;j<=n;j++)                           //考虑所有已访问过的节点         if (!p[j])             maxline[now][j]=maxline[j][now]=max(maxline[j][f],dis);    p[now]=0;    for (int i=st[now];i;i=way[i].nxt)        if (way[i].y!=f&&p[way[i].y])            dfs(way[i].y,now,way[i].v);}int main(){    int T;    scanf("%d",&T);    while (T--)    {        memset(st,0,sizeof(st));         memset(maxline,0,sizeof(maxline));        memset(p,1,sizeof(p));                              memset(pw,1,sizeof(pw));                     //边是否在最小生成树中         scanf("%d%d",&n,&m);        for (int i=1;i<=m;i++)             scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);        tot=0;        int ans1=Kruskal();        dfs(1,-1,0);        int ans2=INF;        for (int i=1;i<=m;i++)            if (pw[i])                ans2=min(ans2,ans1-maxline[e[i].x][e[i].y]+e[i].v);        printf("%d %d\n",ans1,ans2);    }    return 0;}
原创粉丝点击