1. 程式人生 > >AGC 017 E Jigsaw - 結論

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"); }