1 条题解

  • 0
    @ 2025-10-8 16:51:48
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 110;
    struct edge{int x,y,w;};
    vector<edge>E;
    int n,m,rt,in[N],pre[N],scc[N],vis[N];
    int solve()
    {
    	int ans=0;
    	while(True)
    	{
    		memset(in, 0x3f, sizeof(in));
    		memset(pre, 0, sizeof(pre));
    		memset(scc, 0, sizeof(scc));
    		memset(vis, 0, sizeof(vis));
    		
    		for(auto e:E)if(e.x!=e.y && e.w<in[e.y])in[e.y]=e.w,pre[e.y]=e.x;
    		for(int i=1;i<=n;++i)if(i!=rt&&pre[i]==0) return -1;
    		for(int i=1;i<=n;++i)if(i!=rt)ans+=in[i];
    		
    		int cnt = 0;
    		for(int i=1,x;i<=n;++i)if(!scc[i])
    		{
    			for(x=i; x!=rt && !scc[x] && vis[x]!=i; x=pre[x]) vis[x]=i;
    			if(x!=rt && !scc[x])
    			{
    				for(++cnt;!scc[x];x=pre[x]) scc[x]=cnt;
    			}
    		}
    		if(cnt==0) return ans;
    		for(int i=1;i<=n;++i)if(!scc[i]) scc[i]=++cnt;
    		
    		for(int i=0;i<E.size();i++)
    		{
    			E[i].w=E[i].w-in[E[i].y];
    			E[i].x=scc[E[i].x];E[i].y=scc[E[i].y];
    		}
    		n=cnt;
    		rt=scc[rt];
    	}
    }
    int main()
    {
    	scanf("%d%d%d",&n,&m,&rt);
    	for(int i=1,x,y,w;i<=m;++i)
    	{
    		scanf("%d%d%d",&x,&y,&w);if(x==y||y==rt) continue;
    		E.push_back(edge{x,y,w});
    	}
    	printf("%d",solve());
    	return 0;
    }
    • 1

    *【有向图最小生成树】最小树形图[LOJ140](朱刘算法)

    信息

    ID
    718
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    (无)
    递交数
    10
    已通过
    3
    上传者