70求调
查看原帖
70求调
1206518
Nervegas楼主2024/7/11 07:08
#include<bits/stdc++.h>
using namespace std;
const int maxn = 9000010;
//luogu P3275 [SCOI2011] 糖果
//小点向大点建边 如果会至少大1,边权就为1;

struct node{
	int to,nxt,val;
}e[maxn],ee[maxn];

int dfn[maxn],low[maxn],dfs_clock,sccno[maxn],scc_cnt;
int head[maxn],cnt;
stack<int> S;
int sizep[maxn];
int head1[maxn],cnt1;
int w[maxn],ww[maxn];
int dist[maxn];//存缩完点后每个强连通分量的距离 
long long res;

int n,m;

void add(int u,int v,int c){
	e[++cnt].to = v;
	w[cnt] = c;
	e[cnt].nxt = head[u];
	head[u] = cnt;
}

void add1(int u,int v,int c){
	ee[++cnt1].to = v;
	ww[cnt1] = c;
	ee[cnt1].nxt = head1[u];
	head1[u] = cnt1;
}
void tarjan(int u){
	dfn[u] = low[u] = ++dfs_clock;
	S.push(u);
	for(int i = head[u] ; i ; i = e[i].nxt){
		int v = e[i].to;
		if(!dfn[v]){
			tarjan(v);
			low[u] = min(low[u],low[v]);
		}
		else if(!sccno[v]){
			low[u] = min(low[u],dfn[v]);
		}
	}
	if(dfn[u] == low[u]){
		scc_cnt++;
		while(true){
			int v = S.top();
			S.pop();
			sccno[v] = scc_cnt;
			sizep[scc_cnt]++;
			if(v == u){
				break;
			}
		}
	}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	cin >> n >> m;
	for(int i = 1 ; i <= n ; i++){
		add(0,i,1);
	}
	for(int i = 1 ; i <= m ; i++){
		int a,b,c;
		cin >> c >> a >> b;
		if(c == 1){
			add(a, b, 0);
			add(b, a, 0);
		}
		else if(c == 2){
			add(a, b, 1);
		}
		else if(c == 3){
			add(b, a, 0);
		}
		else if(c == 4){
			add(b, a, 1); 
		}
		else{
			add(a, b, 0);
		}
	}
	tarjan(0);
	bool su = true;
	for(int i = 0 ; i <= scc_cnt ; i++){
		for(int j = head[i] ; j ; j = e[j].nxt){
			int v = e[j].to;
			int a = sccno[i];
			int b = sccno[v]; 
			if(a == b){
				//在同一个连通分量;
				if(w[j] > 0){
					su = false;//存在正环,则无解;
					break; 
				} 
			}
			else{
				add1(a, b, w[j]);
			} 
		}
		if(!su){
			break;
		}
	}
	if(!su){
		cout << -1 << endl;
	}
	else{
		for(int i = scc_cnt ; i ; i--){
			for(int j = head1[i] ; j ; j = ee[j].nxt){
				int v = ee[j].to;
				dist[v] = max(dist[v],dist[i] + ww[j]);
			}
	    }
	    for(int i = 1 ; i <= scc_cnt ; i++){
	    	res += (long long)dist[i] * sizep[i];
	    }
	    cout << res << endl;
	}
	return 0;
}
2024/7/11 07:08
加载中...