AGC 017 E Jigsaw - 结论

题目大意:省略建图过程:给你一张图,点分黑白,问能否划分为若干黑点出发到达白点的路径经过所有边恰好一次(有重边,点可以经过任意次)。
题解:关于带下界的可行流,他死了。原因是,即使是有源汇的情况下,一个可行流也未必要从源点出发到达汇点。
结论是,所有黑点出度大于等于入度,白点入度大于等于出度,并且一个存在至少一条边的弱连通分量存在至少一个点,其入度和出度不相等,则可行。否则不可行。

#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define db double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
	int x,ch;while((ch=gc)<'0'||ch>'9');
	x=ch^'0';while((ch=gc)>='0'&&ch<='9')
		x=(x<<1)+(x<<3)+(ch^'0');return x;
}
const int N=100010;int zero,in[N],out[N],fa[N],ok[N],vis[N];
inline int F(int x) { return x+zero; }
inline int findf(int x) { int fx=x,y;while(fx^fa[fx]) fx=fa[fx];while(x^fx) y=fa[x],fa[x]=fx,x=y;return fx; }
int main()
{
	int n=inn(),h=inn();zero=h+1;
	rep(i,-h,h) fa[F(i)]=F(i);
	rep(i,1,n)
	{
		int a=inn(),b=inn(),c=inn(),d=inn(),L,R;
		if(c) L=-c;else L=a;if(d) R=d;else R=-b;
		out[F(L)]++,in[F(R)]++;
		L=findf(F(L)),R=findf(F(R));
		if(L^R) fa[L]=R;
	}
	rep(i,-h,h)
	{
		if(F(i)>zero&&in[F(i)]>out[F(i)]) return !printf("NO\n");
		if(F(i)<zero&&in[F(i)]<out[F(i)]) return !printf("NO\n");
		if(in[F(i)]||out[F(i)]) vis[findf(F(i))]=1;
		if(in[F(i)]^out[F(i)]) ok[findf(F(i))]=1;
	}
	rep(i,-h,h) if(vis[F(i)]&&!ok[findf(F(i))]) return !printf("NO\n");
	return !printf("YES\n");
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/83147904
017
今日推荐