A collated collection of algorithm templates: ACM templates
table of Contents
The smallest tree graph of a directed graph given a root
Given a graph with n nodes and m directed edges. Try to find a minimum tree graph rooted at node r, and output the sum of the weights of each edge of the minimum tree graph. If there is no
minimum tree graph rooted at r , output −1.
#include<bits/stdc++.h>
using namespace std;
const int N=106,M=10006,inf=2e8;
int n,m,rt,t,cnt=0,id[N],pre[N],ine[N],vis[N];
struct line{
int x,y,c;}q[M];
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
int zhuliu(){
int ans=0;
while(true){
cnt=0;
for(int i=1;i<=n;++i) ine[i]=inf,vis[i]=0,id[i]=0;//预处理
for(int i=1;i<=m;++i) if(q[i].x!=q[i].y&&ine[q[i].y]>q[i].c) ine[q[i].y]=q[i].c,pre[q[i].y]=q[i].x;//每个点的最短边
for(int i=1;i<=n;++i) if(i!=rt&&ine[i]==inf) return -1;//有点无最短边
for(int i=1;i<=n;++i){
if(i==rt) continue;
ans+=ine[i],t=i;
while(vis[t]!=i&&!id[t]&&t!=rt) vis[t]=i,t=pre[t];
//能走到环的点或者换上的点停下
if(!id[t]&&t!=rt){
id[t]=++cnt; //将环上的点标记为新的环
for(int o=pre[t];o!=t;o=pre[o]) id[o]=cnt;
}
}//找环
if(!cnt) break;//无环结束
for(int i=1;i<=n;++i) if(!id[i]) id[i]=++cnt;
for(int i=1;i<=m;++i){
t=q[i].y,q[i].x=id[q[i].x],q[i].y=id[q[i].y];
if(q[i].x!=q[i].y) q[i].c-=ine[t];
}
n=cnt,rt=id[rt];
//去旧图,换新图
}
return ans;
}
int main(){
n=read(),m=read(),rt=read();
for(int i=1;i<=m;++i) q[i].x=read(),q[i].y=read(),q[i].c=read();
printf("%d\n",zl());
return 0;
}
Dendrogram for a given root
Find a tree graph with no definite root: create a super root r and use it as the root to run the algorithm. Just connect r to each point of the original graph with an edge whose weight is greater than the weight of all edges in the original graph, and select these The edge is definitely not worthwhile, so only one will be chosen.
The method of judging no solution
Unsolvable tricks: enumerate each point i from small to large, add edges (i, (i + 1)% n + 1, + ∞) (i,(i+1)\%n+ 1,+\infty)(i,(i+1)%n+1,+ ∞ ) , so if you finally get the answer+ ∞ +\infty+ ∞ , then there is no solution.