2019 UESTC ACM Training for Graph[A] (二分+拓扑排序)

知识共享许可协议 Creative Commons

题意:给你一个n个点m条边的带权有向图,让你翻转一些边使得这个图无环,翻转的代价是所有边权中的最大值,你需要让这个代价最小。
首先在图论中有这样一个结论:若给一张无环的有向图,让你给图中某些点对间连有向边,总有一种方案使得图依旧是无环的。
因为将原图进行拓扑排序后,对于每个点对,从拓扑序较小的点连向拓扑序较大的点,若拓扑序相同则随意。图一定的无环的。
因此我们就将题意转化为:在给出的图中删去一些边,使得图中没有环,同时要删去的最大边的权值最小。
之所以可以这么转化,是因为如果从删去相应边之后的图中开始“加边”,那么就可以把删去的边加上,如果会产生环就改变这条边的方向,根据上面的结论,一定可以使得新的图无环。
最大值最小,想到可以二分一下答案。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#include<map>
#define LL long long
using namespace std;
const LL inf=0x3f3f3f3f;
const LL maxn=2e5+5;
inline void _read(LL &x){
    char t=getchar();bool sign=true;
    while(t<'0'||t>'9')
    {if(t=='-')sign=false;t=getchar();}
    for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';
    if(!sign)x=-x;
}
struct Edge{
	LL from,to,d;
};
LL n,m,mark[maxn],pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
stack<int>S;
vector<LL>G[maxn];
vector<Edge>edges;
void dfs(LL u){
	pre[u]=lowlink[u]=++dfs_clock;
	S.push(u);
	for(LL i=0;i<G[u].size();i++){
		if(mark[G[u][i]])continue;
		Edge e=edges[G[u][i]];
		LL v=e.to;
		if(!pre[v]){
			dfs(v);
			lowlink[u]=min(lowlink[u],lowlink[v]);
		}
		else if(!sccno[v])lowlink[u]=min(lowlink[u],pre[v]);
	}
	if(lowlink[u]==pre[u]){
		scc_cnt++;
		for(;;){
			int x=S.top();S.pop();
			sccno[x]=scc_cnt;
			if(x==u)break;
		}
	}
}
bool check(LL k){
	memset(mark,0,sizeof(mark));
	memset(pre,0,sizeof(pre));
	memset(lowlink,0,sizeof(lowlink));
	memset(sccno,0,sizeof(sccno));
	dfs_clock=scc_cnt=0;
	for(LL i=0;i<edges.size();i++)
		if(edges[i].d<=k)mark[i]=1;
	for(LL i=1;i<=n;i++)
		if(!pre[i])dfs(i);
	return scc_cnt==n;
}
int main(){
	_read(n);_read(m);
	for(LL i=1;i<=m;i++){
		LL x,y,z;
		_read(x);_read(y);_read(z);
		edges.push_back((Edge){x,y,z});
		G[x].push_back(edges.size()-1);
	}
	LL L=0,R=2e9+3;
	while(L<R){
		LL mid=(L+R)>>1;
		if(check(mid))R=mid;
		else L=mid+1;
	}
	cout<<R;
}

猜你喜欢

转载自blog.csdn.net/getsum/article/details/91844017
今日推荐