此题使用并查集

将多余的航班删去(有环时)  少的航班加上 使得全图联通

答案不唯一 所以自己写的和题中实例输出不一样也不一定错

还有就是花费最大会超过 long 所以直接用 64位

 

 

http://acm.timus.ru/problem.aspx?space=1&num=1709

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>

using namespace std;

char ans[101][101];
int f[101];
inline int find(int x)//这个你懂得
{
    if(f[x]!=x)
    f[x]=find(f[x]);
    return f[x];
}
int main()
{
    //freopen("D:\\6\\bin\\Debug\\hu.txt","r",stdin);
    int n,d,a,i,j,l1,l2;
    char k;
    long long pay;
    cin>>n>>d>>a;
    for(i=1;i<=n;i++)
    f[i]=i;
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    ans[i][j]='0';
    pay=0;
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
        cin>>k;
        if(k=='1'&&i<j)
        {
           l1=find(i);l2=find(j);
           if(l1==l2)//有环 删掉
           {ans[i][j]=ans[j][i]='d';pay+=d;}
           else
           f[l1]=l2;//没有环 使联通
        }
    }
    for(i=2;i<=n;i++)//将少的航班加上 (不唯一)
    if(find(i)!=find(1))
    {
        ans[i][1]=ans[1][i]='a';
        f[find(i)]=find(1);
        pay+=a;
    }
    cout<<pay<<endl;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        cout<<ans[i][j];
        cout<<endl;
    }
    return 0;
}

posted on 2011-11-24 16:23  夜->  阅读(685)  评论(0编辑  收藏  举报