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 @   liyishui  阅读(27)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示