滾粗了的hansbug在收拾舊語文書,然而他發現了什麼奇妙的東西。
蒟蒻hansbug在一本語文書裡面發現了一本答案,然而他卻明明記得這書應該還包含乙份練習題。然而出現在他眼前的書多得數不勝數,其中有書,有答案,有練習冊。已知乙個完整的書冊均應該包含且僅包含一本書、一本練習冊和乙份答案,然而現在全都亂做了一團。許多書上面的字跡都已經模糊了,然而hansbug還是可以大致判斷這是一本書還是練習冊或答案,並且能夠大致知道一本書和答案以及一本書和練習冊的對應關係(即僅僅知道某書和某答案、某書和某練習冊有可能相對應,除此以外的均不可能對應)。既然如此,hansbug想知道在這樣的情況下,最多可能同時組合成多少個完整的書冊。
第一行包含三個正整數n1、n2、n3,分別表示書的個數、練習冊的個數和答案的個數。
第二行包含乙個正整數m1,表示書和練習冊可能的對應關係個數。
接下來m1行每行包含兩個正整數x、y,表示第x本書和第y本練習冊可能對應。($1 \le x \le n1,1\le y\le n2 $)
第m1+3行包含乙個正整數m2,表述書和答案可能的對應關係個數。
接下來m2行每行包含兩個正整數x、y,表示第x本書和第y本答案可能對應。(\(1 \le x \le n1,1 \le y \le n3\))
輸出包含乙個正整數,表示最多可能組成完整書冊的數目。
5 3 4
54 3
2 25 2
5 15 3
51 3
3 12 2
3 34 3
2
如題,n1=5,n2=3,n3=4,表示書有5本、練習冊有3本、答案有4本。
m1=5,表示書和練習冊共有5個可能的對應關係,分別為:書4和練習冊3、書2和練習冊2、書5和練習冊2、書5和練習冊1以及書5和練習冊3。
m2=5,表示數和答案共有5個可能的對應關係,分別為:書1和答案3、書3和答案1、書2和答案2、書3和答案3以及書4和答案3。
所以,以上情況的話最多可以同時配成兩個書冊,分別為:書2+練習冊2+答案2、書4+練習冊3+答案3。
對於資料點1, 2, 3,\(m1,m2\le 20\)
對於資料點4~10,\(m1,m2 \le 20000\)
網路最大流。這裡不詳細講,請大家先掌握。
注意,以下出現的所有邊邊權皆為1,且其反向邊邊權為0我們以書、練習冊、答案為點建圖。
像這樣:
s(=0)表示額外建的乙個起始點,ri(=i+n1+n1)表示第i本練習冊,di(=i+n1+n1+n2)表示第i本答案,由於書只有一本,而網路流處理只經過乙個點不方便,我們採用一種神奇方法——拆點!也就是說,把一本書看做兩個點,要匹配這本書必須經過這本書兩點之間的邊,這樣就可以控制這本書只匹配一次。如圖,pi(=i)、pi'(=i+n1)表示第i本書。
然後建邊。如圖,將s與所有ri相連,將所有的di與t相連,s作為源點,t作為匯點。如果pi能匹配rj,就將pi與rj相連。如果pi能匹配dj,就將dj與pi'之間相連。當然,pi與pi'之間也要連一條邊。
然後就可以套網路最大流辣。最後得出的答案即為最多的數目。
#includeusing namespace std;
#define open(s) freopen( s".in", "r", stdin ), freopen( s".out", "w", stdout )
#define maxn 40005
#define maxm 150000
int n1, n2, n3;
int m1, m2;
int hd[maxn], nxt[maxm << 1], to[maxm << 1], val[maxm << 1], tot(1);
int ans, dis[maxn];
queueq;
bool vis[maxn];
int x, y;
int s, t;
void add( int x, int y, int z )
bool bfs()
} return 0;
}int dfs( int x, int fl )
} return fl - res;
}int main()
scanf( "%d", &m2 );
for ( int i = 1; i <= m2; ++i )
s = 0; t = 1 + n1 + n1 + n2 + n3;
for ( int i = 1; i <= n2; ++i ) add( s, i + n1, 1 ), add( i + n1, s, 0 );
for ( int i = 1; i <= n3; ++i ) add( i + n1 + n2, t, 1 ), add( t, i + n1 + n2, 0 );
for ( int i = 1; i <= n1; ++i ) add( i, i + n1 + n2 + n3, 1 ), add( i + n1 + n2 + n3, i, 0 );
int t;
while( bfs() )
while( ( t = dfs( s, 0x7f7f7f7f ) ) > 0 ) ans += t;
printf( "%d\n", ans );
return 0;
}
洛谷 P1231 教輔的組成
題目背景 滾粗了的hansbug在收拾舊語文書,然而他發現了什麼奇妙的東西。題目描述 蒟蒻hansbug在一本語文書裡面發現了一本答案,然而他卻明明記得這書應該還包含乙份練習題。然而出現在他眼前的書多得數不勝數,其中有書,有答案,有練習冊。已知乙個完整的書冊均應該包含且僅包含一本書 一本練習冊和乙份...
洛谷 P1231 教輔的組成
滾粗了的hansbug在收拾舊語文書,然而他發現了什麼奇妙的東西。蒟蒻hansbug在一本語文書裡面發現了一本答案,然而他卻明明記得這書應該還包含乙份練習題。然而出現在他眼前的書多得數不勝數,其中有書,有答案,有練習冊。已知乙個完整的書冊均應該包含且僅包含一本書 一本練習冊和乙份答案,然而現在全都亂...
P1231 教輔的組成
題目 啊,又是煩人的拆點,其實網路瘤一堆題都是拆點,本題顯然要把書,練習冊 53 答案 學生的福音 分開,但是,書作為中轉的地方,是具有唯一性的,不能2本53都配同一本書,這時我們還需要用拆點思想保障書是唯一的。code include include include include include...