POJ1904 强联通(最大匹配可能性)
生活随笔
收集整理的這篇文章主要介紹了
POJ1904 强联通(最大匹配可能性)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 有n個王子,n個公主,然后給你每個王子喜歡的公主,最后問你在不影響最大匹配的前提下,每個王子可以匹配那些公主。
思路:
? ? ? 有n個王子,n個公主,然后給你每個王子喜歡的公主,最后問你在不影響最大匹配的前提下,每個王子可以匹配那些公主。
思路:
? ? ? 是hdu4685的減弱版,之前研究過hdu4685所以這個題目直接水過了,對于這個題目,我們把王子和他喜歡的公主之間建連邊,建立一個二分圖,然后對于題目給的已經匹配好了的(有的題目沒給,直接就自己跑一邊二分匹配自己找),之間建立反邊,就是建立公主到王子的邊,然后一遍強聯通,如果同意個分量里的男女可以匹配。這樣記錄每一個然后sort一下就行了。
#include<stdio.h> #include<string.h> #include<algorithm> #include<stack>#define N_node 5000 #define N_edge 1000000using namespace std;typedef struct {int to ,next; }STAR;STAR E1[N_edge] ,E2[N_edge]; int list1[N_node] ,list2[N_node] ,tot; int Belong[N_node] ,cont; int mark[N_node]; int ans[N_node]; stack<int>st;void add(int a ,int b) {E1[++tot].to = b;E1[tot].next = list1[a];list1[a] = tot;E2[tot].to = a;E2[tot].next = list2[b];list2[b] = tot; }void DFS1(int s) {mark[s] = 1;for(int k = list1[s] ;k ;k = E1[k].next){int to = E1[k].to;if(!mark[to]) DFS1(to);}st.push(s); }void DFS2(int s) {mark[s] = 1;Belong[s] = cont;for(int k = list2[s] ;k ;k = E2[k].next){int to = E2[k].to;if(!mark[to]) DFS2(to);} }int main () {int n ,i ,j ,a ,nn;while(~scanf("%d" ,&n)){memset(list1 ,0 ,sizeof(list1));memset(list2 ,0 ,sizeof(list2));tot = 1;for(i = 1 ;i <= n ;i ++){scanf("%d" ,&nn);for(j = 1 ;j <= nn ;j ++){scanf("%d" ,&a);add(i ,a + n);}}for(i = 1 ;i <= n ;i ++){scanf("%d" ,&a);add(a + n ,i);}memset(mark ,0 ,sizeof(mark));while(!st.empty()) st.pop();for(i = 1 ;i <= n + n ;i ++){if(!mark[i]) DFS1(i);}memset(mark ,0 ,sizeof(mark));cont = 0;while(!st.empty()){int to = st.top();st.pop(); if(!mark[to]){cont ++;DFS2(to);}} for(i = 1 ;i <= n ;i ++){int tt = 0;for(int k = list1[i] ;k ;k = E1[k].next){int to = E1[k].to;if(Belong[i] == Belong[to])ans[++tt] = to - n;}sort(ans + 1 ,ans + tt + 1);printf("%d" ,tt);for(j = 1 ;j <= tt ;j ++)printf(" %d" ,ans[j]);puts("");}}return 0; }
總結
以上是生活随笔為你收集整理的POJ1904 强联通(最大匹配可能性)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ2186 强联通
- 下一篇: POJ 3301 三分(最小覆盖正方形)