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);
        }
    }
}

 

posted @ 2021-10-30 11:29  liyishui  阅读(26)  评论(0编辑  收藏  举报