1. 程式人生 > 其它 >poj1679+uva10600+uva10462 次小生成樹

poj1679+uva10600+uva10462 次小生成樹

這三貨是一套的,改改輸入輸出

注意在判斷次小生成樹時,要保證最後用到的邊的總數為n-1,否則非法.

---

前兩道wa了好久,一直放著,直到今天開啟uva10462才意識到題目保證最小生成樹存在但沒保證次小生成樹一定存在..

Poj 1679

#include <iostream>
#include <math.h>
#include <string.h>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include 
<algorithm> #include <cstdio> using namespace std; int fa[500000],cnt=0,a[500000],head[500000]; struct lys{ int from,to,cost,next; }edge[20000]; void add(int from,int to,int cost) { cnt++; edge[cnt].from=from; edge[cnt].to=to; edge[cnt].cost=cost; edge[cnt].next=head[from]; head[
from]=cnt; } int find(int x) { if(fa[x]!=x) { fa[x]=find(fa[x]); } return fa[x]; } bool cmp(lys a,lys b) { return a.cost<b.cost; } int main() { // freopen("lys.in","r",stdin); int t,n,m; cin>>t; for(int i=1;i<=t;i++) { cnt=0; memset(a,
0,sizeof(a)); memset(head,0,sizeof(head)); scanf("%d%d",&n,&m); for(int j=1;j<=m;j++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } sort(edge+1,edge+cnt+1,cmp); for(int j=1;j<=n;j++) fa[j]=j; int ans=0,count=0; for(int j=1;j<=cnt;j++) { int f1=find(edge[j].from),fb=find(edge[j].to); if(f1!=fb) { count++; a[count]=j; ans+=edge[j].cost; fa[f1]=fb; } } int minn=20211030; for(int j=1;j<=count;j++) //列舉該次不用的邊 { int ans2=0,use=0; for(int k=1;k<=n;k++) fa[k]=k; for(int k=1;k<=cnt;k++) { if(k==a[j]) continue; int f1=find(edge[k].from),f2=find(edge[k].to); if(f1!=f2) { use++; fa[f1]=f2; ans2+=edge[k].cost; } } if(use==n-1) minn=min(minn,ans2); } if(minn==ans) { printf("Not Unique!\n"); } else cout<<ans<<endl; } }

Uva 10600

#include <iostream>
#include <math.h>
#include <string.h>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <algorithm>
#include <cstdio>
using namespace std;
int fa[500000],cnt=0,a[500000],head[500000];
struct lys{
    int from,to,cost,next;
}edge[20000];
void add(int from,int to,int cost)
{
    cnt++;
    edge[cnt].from=from;
    edge[cnt].to=to;
    edge[cnt].cost=cost;
    edge[cnt].next=head[from];
    head[from]=cnt;
}
int find(int x)
{
    if(fa[x]!=x)
    {
        fa[x]=find(fa[x]);
    }
    return fa[x];
}
bool cmp(lys a,lys b)
{
    return a.cost<b.cost;
}
int main()
{
 //freopen("lys.in","r",stdin);
 
    int t,n,m;
    cin>>t;
    for(int i=1;i<=t;i++)
    {   
        cnt=0;
        memset(a,0,sizeof(a));
        memset(head,0,sizeof(head));
        
        scanf("%d%d",&n,&m);
        for(int j=1;j<=m;j++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        
        sort(edge+1,edge+cnt+1,cmp);
    
       for(int j=1;j<=n;j++) fa[j]=j;
       
       
       int ans=0,count=0;
       
       for(int j=1;j<=cnt;j++)
       {
             int f1=find(edge[j].from),fb=find(edge[j].to);
             if(f1!=fb)
             {  
                count++;
                a[count]=j;
             ans+=edge[j].cost;
             fa[f1]=fb;          
          }
       }
    
       
       int minn=20211030;
       
       for(int j=1;j<=count;j++)
       //列舉該次不用的邊
        {
        int ans2=0,use=0;
        for(int k=1;k<=n;k++) fa[k]=k;
        
        for(int k=1;k<=cnt;k++)
        {
            if(k==a[j]) continue;
            
            int f1=find(edge[k].from),f2=find(edge[k].to);
            
            if(f1!=f2)
            {   use++;
                fa[f1]=f2;
                ans2+=edge[k].cost;
            }
        }
          if(use==n-1) minn=min(minn,ans2);    
        }
        
        cout<<ans<<" "<<minn<<endl;
    }
}

Uva 10462

#include <iostream>
#include <math.h>
#include <string.h>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <algorithm>
#include <cstdio>
using namespace std;
int fa[500000],cnt=0,a[500000],head[500000];
struct lys{
    int from,to,cost,next;
}edge[20000];
void add(int from,int to,int cost)
{
    cnt++;
    edge[cnt].from=from;
    edge[cnt].to=to;
    edge[cnt].cost=cost;
    edge[cnt].next=head[from];
    head[from]=cnt;
}
int find(int x)
{
    if(fa[x]!=x)
    {
        fa[x]=find(fa[x]);
    }
    return fa[x];
}
bool cmp(lys a,lys b)
{
    return a.cost<b.cost;
}
int main()
{

    int t,n,m;
    cin>>t;
    for(int i=1;i<=t;i++)
    {   
        cnt=0;
        memset(a,0,sizeof(a));
        memset(head,0,sizeof(head));
        
        scanf("%d%d",&n,&m);
        for(int j=1;j<=m;j++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        
        sort(edge+1,edge+cnt+1,cmp);
    
       for(int j=1;j<=n;j++) fa[j]=j;
       
       
       int ans=0,count=0;
       
       for(int j=1;j<=cnt;j++)
       {
             int f1=find(edge[j].from),fb=find(edge[j].to);
             if(f1!=fb)
             {  
                count++;
                a[count]=j;
             ans+=edge[j].cost;
             fa[f1]=fb;          
          }
       }
    
       if(count<n-1)
       {
           printf("Case #%d : No way\n",i);
           continue;
       }
       
       int minn=20211030;
       
       for(int j=1;j<=count;j++)
       //列舉該次不用的邊
        {
        int ans2=0,use=0;
        for(int k=1;k<=n;k++) fa[k]=k;
        
        for(int k=1;k<=cnt;k++)
        {
            if(k==a[j]) continue;
            
            int f1=find(edge[k].from),f2=find(edge[k].to);
            
            if(f1!=f2)
            {   use++;
                fa[f1]=f2;
                ans2+=edge[k].cost;
            }
        }
          if(use==n-1) minn=min(minn,ans2);    
        }
        
        if(minn==20211030)
        {
            printf("Case #%d : No second way\n",i);
            continue;
        }
        else 
        {
            printf("Case #%d : %d\n",i,minn);
        }
    }
}