码迷,mamicode.com
首页 > 其他好文 > 详细

HDU2121 Ice_cream’s world II

时间:2019-12-24 18:52:34      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:n+1   lse   std   ret   code   出现   amp   c++   最小树形图   

题意

题意即求不定根最小树形图。

我们建一个虚拟节点\(n+1\)\([1,n]\)连边权为所有边权之和的边,这样能保证这种边只会出现一次。之后跑最小树形图,并记录\(root\)连向的点是谁,那就是根。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1010;
const int maxm=10010;
const ll inf=1e18;
int n,m,pos;
int vis[maxn],pre[maxn],col[maxn];
ll mindis[maxn];
struct Edge{int u,v;ll w;}E[maxm];
inline ll solve(int root,int n,int m)
{
    ll res=0;
    while(2333)
    {
        int cnt=0;
        for(int i=1;i<=n;i++)pre[i]=vis[i]=col[i]=0,mindis[i]=inf;
        for(int i=1;i<=m;i++)
            if(E[i].u!=E[i].v&&E[i].w<mindis[E[i].v])
            {
                pre[E[i].v]=E[i].u,mindis[E[i].v]=E[i].w;
                if(E[i].u==root)pos=i;
            }
        mindis[root]=0;
        for(int i=1;i<=n;i++)
        {
            if(mindis[i]==inf)return -1;
            res+=mindis[i];
            int x=i;
            while(x!=root&&vis[x]!=i&&!col[x])vis[x]=i,x=pre[x];
            if(x!=root&&!col[x])
            {
                col[x]=++cnt;
                int y=pre[x];
                while(y!=x)col[y]=cnt,y=pre[y];
            }
        }
        if(!cnt)return res;
        for(int i=1;i<=n;i++)if(!col[i])col[i]=++cnt;
        for(int i=1;i<=m;i++)
        {
            int delta=mindis[E[i].v];
            E[i].u=col[E[i].u],E[i].v=col[E[i].v];
            if(E[i].u!=E[i].v)E[i].w-=delta;
        }
        n=cnt;root=col[root];
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        ll sum=0;
        for(int i=1;i<=m;i++)scanf("%d%d%lld",&E[i].u,&E[i].v,&E[i].w);
        for(int i=1;i<=m;i++)E[i].u++,E[i].v++,sum+=E[i].w;
        sum++;
        for(int i=m+1;i<=n+m;i++)E[i]=(Edge){n+1,i-m,sum};
        ll res=solve(n+1,n+1,n+m);
        if(res==-1||res-sum>=sum)puts("impossible");
        else printf("%lld %d\n",res-sum,pos-m-1);
        puts("");
    }
    return 0;
}

HDU2121 Ice_cream’s world II

标签:n+1   lse   std   ret   code   出现   amp   c++   最小树形图   

原文地址:https://www.cnblogs.com/nofind/p/12092801.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!