AGC 017 E Jigsaw - 結論
阿新 • • 發佈:2018-11-10
題目大意:省略建圖過程:給你一張圖,點分黑白,問能否劃分為若干黑點出發到達白點的路徑經過所有邊恰好一次(有重邊,點可以經過任意次)。
題解:關於帶下界的可行流,他死了。原因是,即使是有源匯的情況下,一個可行流也未必要從源點出發到達匯點。
結論是,所有黑點出度大於等於入度,白點入度大於等於出度,並且一個存在至少一條邊的弱連通分量存在至少一個點,其入度和出度不相等,則可行。否則不可行。
#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");
}