模板也能WA?我枯了!!!
查看原帖
模板也能WA?我枯了!!!
326910
LeBronGod楼主2021/7/14 16:57
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define endl '\n'
#define int long long
using namespace std;
typedef pair<int,int> pii;
const int maxn = 1e6+10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
const double esp = 1e-7;
int n,m,r;
int in[maxn],cir[maxn],vis[maxn],pre[maxn];
struct node {
	int u,v,w;
}e[maxn];
int zhuliu() {
	int res = 0,u,v;
	while(1) {
		//先为每个点找到其最小的入边 
		for(int i=1;i<=n;i++) {
			in[i] = INF; 
		}
		for(int i=1;i<=m;i++) {
			if(e[i].u != e[i].v && e[i].w<in[e[i].v]) {
				in[e[i].v] = e[i].w;
				pre[e[i].v] = e[i].u;
			}
		}
		for(int i=1;i<=n;i++) {
			if(i != r && in[i] == INF) {
				return -1;//有孤立的点无法连接成一个最小树形图 
			}
		}
		//接下来找环 
		memset(cir,-1,sizeof(cir));
		memset(vis,-1,sizeof(vis));
		int cnt = 0;
		in[r] = 0;
		for(int i=1;i<=n;i++) {
			res += in[i];
			v = i;
			while(vis[v] != i && cir[v] == -1 && v != r) {//直到找到以i为起点终点的环 或 找到别的环 或 找到根节点截止 
				vis[v] = i;
				v = pre[v];
			}
			if(cir[v] == -1 && v != r) {//找到了以i为起点终点的环,给这些个环里的点编号 
				cir[v] = ++cnt;
				for(int u=pre[v];u!=v;u=pre[u]) {
					cir[u] = cnt;
				} 
			} 
		}
		if(cnt == 0) break; //没有环,那么就都是独立的点这时就找到解了 
		
		for(int i=1;i<=n;i++) {//给那些没成环的点也重新编号 
			if(cir[i] == -1) {
				cir[i] = ++cnt;
			}
		}
		
		//接下来就是缩点
		for(int i=1;i<=m;i++) {
			v = e[i].v;
			e[i].u = cir[e[i].u];
			e[i].v = cir[e[i].v];
			if(e[i].u != e[i].v) {
				e[i].w -= in[e[i].v]; 
			}
		} 
		n = cnt;
		r = cir[r];
	}
	return res;
}
signed main()
{
	cin>>n>>m>>r;
	for(int i=1;i<=m;i++) {
		cin>>e[i].u>>e[i].v>>e[i].w;
	}
	cout<<zhuliu()<<endl; 
}
2021/7/14 16:57
加载中...