Trail Maintenance LightOJ - 1123

点击打开链接

每次加一条边 在加新边后的图中求最小生成树

先想到的就是把前i条边全部排序 但是m很大会超时

发现n很小 每次求出最小生成树时有用的边最多(n-1)条 所以每次只给n条边排序就好 求完生成树后把没用的那条边换成新边 再继续

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct node
{
    int u;
    int v;
    int w;
};

node edge[6010];
int f[210];
int n,m;

bool cmp(node n1,node n2)
{
    return n1.w<n2.w;
}

int getf(int p)
{
    if(f[p]==p) return p;
    else
    {
        f[p]=getf(f[p]);
        return f[p];
    }
}

bool unite(int u,int v)
{
    int fu,fv;
    fu=getf(u);
    fv=getf(v);
    if(fu!=fv)
    {
        f[fv]=fu;
        return true;
    }
    else return false;
}

int main()
{
    int book[210];
    int t,cas,i,j,sum,cnt;
    scanf("%d",&t);
    for(cas=1;cas<=t;cas++)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
        }
        printf("Case %d:\n",cas);
        for(i=1;i<=min(m,n-2);i++)
        {
            printf("-1\n");
        }
        if(m>=n-1)
        {
            for(i=1;i<=n;i++) f[i]=i;
            sum=0,cnt=0;
            for(i=1;i<=n-1;i++)
            {
                if(unite(edge[i].u,edge[i].v))
                {
                    sum+=edge[i].w,cnt++;
                }
            }
            if(cnt==n-1) printf("%d\n",sum);
            else printf("-1\n");
            for(i=n;i<=m;i++)
            {
                swap(edge[i],edge[n]);
                sort(edge+1,edge+n+1,cmp);
                for(j=1;j<=n;j++)
                {
                    f[j]=j;
                    book[j]=0;
                }
                sum=0,cnt=0;
                for(j=1;j<=n;j++)
                {
                    if(unite(edge[j].u,edge[j].v))
                    {
                        book[j]=1;
                        sum+=edge[j].w,cnt++;
                    }
                    if(cnt==n-1) break;
                }
                if(cnt==n-1) printf("%d\n",sum);
                else printf("-1\n");
                for(j=1;j<=n;j++)
                {
                    if(!book[j])
                    {
                        swap(edge[j],edge[n]);
                        break;
                    }
                }
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/81062193