HeRaNO's NOIP CSP Round Day 2 T2 PESTC

 

 

 

 

 对于我这种菜鸡来说还是挺有迷惑性的。

在考场发现答案问的是跟最值有关的数量,想到二分,结果果然具有单调性,考虑二份答案+验证

其实什么反转什么的,可以不用去管他,对于长度小于二分答案mid的道路,不去考虑

只要是在图中出现了环,就一定不行

所以这道题变成了判环的问题,tarjan和dfs均可

AC code

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;++i)
#define dec(i,j,k) for(re int i=j;i>=k;--i)
#define ra(i,u) for(re int i=head[u];i;i=e[i].nxt)
using namespace std;
const int maxn=200010;
const int maxm=300010;
inline int read()
{
	re int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9') {x=x*10+(ch^48); ch=getchar();}
	return x*f;
}
int head[maxn],dfn[maxn],low[maxn],sta[maxn],scc[maxn],tong[maxn];
int cnt,n,m,tot,top,maxx=-1,num;
bool vis[maxn];
struct node
{
	int to,nxt,w;
}e[maxm];
inline void add(int u,int v,int w)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	e[cnt].w=w;
	head[u]=cnt;
}
bool flag=0;
inline void tarjan(int x,int k)
{
	dfn[x]=low[x]=++tot;
    sta[++top]=x;
    ra(i,x)
    {
    	if(e[i].w<=k) continue;
    	re int v=e[i].to;
    	if(!dfn[v])
		{
			tarjan(v,k);
			low[x]=min(low[x],low[v]);
		}
		else if(!scc[v]) low[x]=min(low[x],dfn[v]);
    }
    if(low[x]==dfn[x])
    {
    	scc[x]=++num;
    	++tong[num];
    	while(sta[top]!=x)
    	{
    		scc[sta[top--]]=num;
    		++tong[num];
    		/*if(tong[num]>=2)
    		{
    			flag=1; return;
    		}*/
    	}
		--top;
    }
}
inline void clear()
{
	inc(i,1,n)
	{
		dfn[i]=low[i]=sta[i]=scc[i]=0;
		vis[i]=0;
	}
	memset(tong,0,sizeof(tong));
	tot=0; top=0; num=0;
	return;
}
inline bool check(int x)
{
	clear();
//	flag=0;
	inc(i,1,n)
	{
		if(!dfn[i])
		{
			tarjan(i,x);
//			cout<<"QAQ"<<endl;
//			if(flag==1) return 0;
		}
	}
	inc(i,1,num)
	{
		if(tong[i]>=2) return 0;
	}
	return 1;
}
int main()
{
//	freopen("test6.in","r",stdin);
	int l=0,r=2e9,ans=2e9;
	n=read(); m=read();
	re int xx,yy,zz;
	inc(i,1,m)
	{
		xx=read(); yy=read(); zz=read();
		add(xx,yy,zz); maxx=max(maxx,zz);
	}
	l=0,r=maxx,ans=maxx;
	while(l<=r)
	{
		re int mid=(l+r)>>1;
//		cout<<mid<<endl;
		if(check(mid)) ans=mid,r=mid-1;
		else l=mid+1;
//		cout<<ans<<endl;
	}
	cout<<ans<<endl;
}

 我居然最开始数组开小了。。。 这就是考试睡觉的下场,写的代码前后断片。。

 

posted @ 2019-11-08 18:40  ZzTzZ  阅读(205)  评论(0)    收藏  举报