poj1741,poj 1904

 2023-12-07 阅读 26 评论 0

摘要:題意:國王有n個兒子,現在有n個美女,每個兒子都有若干個夢中情人,現在已經有一個方案使每個王子都能與自己的夢中情人之一結婚。現在要求的是,對于每個兒子能選擇的配偶是誰(最終每個兒子都能結成婚)? 分析:這

題意:國王有n個兒子,現在有n個美女,每個兒子都有若干個夢中情人,現在已經有一個方案使每個王子都能與自己的夢中情人之一結婚。現在要求的是,對于每個兒子能選擇的配偶是誰(最終每個兒子都能結成婚)?

分析:這個題的建圖方法很特別。為了充分利用條件,即最后給出的那個完美匹配,將每個王子向他的夢中情人作一條有向邊,完美匹配方案中,美女向匹配的王子作一條有向邊。求出圖中的強連通分量,與王子在同一個強連通分量且該王子喜歡的美女就是答案。

正確性:王子集合{x1,x2,......,xn},美女集合{y1,y2,......,yn},假設在原完美匹配方案中每個匹配都是(xi,yi),顯然yi是xi的一個選項。假如xi選了yj(j!=i),則原先與yj匹配的王子xj要找另一個女人,yi要與另一個王子匹配,假如xj喜歡yi,那么yj就可以是xi的另一個選項了,假如xj不喜歡yi,那么就繼續下去拆散現有的完美匹配,直到有個王子喜歡yi。所以這樣就相當于要找一條由xi出發到yi的通路(等價于由xi出發回到xi的回路),只要這樣的回路存在,王子就可以與回路中任意一個他喜歡的美女匹配了。這樣也就相當于求包含xi的強連通分量。(注意:求出強連通分量之后,只有王子喜歡的美女才能匹配)。

View Code
 1 #include<cstdio>
 2 #include<vector>
 3 #include<stack>
 4 #include<algorithm>
 5 using namespace std;
 6 stack<int> s;
 7 vector<int> arc[5005],group[5005];
 8 bool visited[5005],instack[5005],matrix[2001][2001];
 9 int counter,low[5005],num[5005],sn,set[5005],n;
10 void tarjan(int u)
11 {
12     int i,v;
13     num[u]=low[u]=++counter;
14     visited[u]=true;
15     instack[u]=true;
16     s.push(u);
17     for(i=0;i<arc[u].size();i++)
18     {
19         v=arc[u][i];
20         if(!visited[v])
21         {
22             tarjan(v);
23             low[u]=min(low[v],low[u]);
24         }
25         else if(instack[v])
26             low[u]=min(low[u],num[v]);
27     }
28     if(num[u]==low[u])
29     {
30         do
31         {
32             v=s.top();
33             if(v>n)//v is a girl
34                 group[sn].push_back(v);
35             else
36                 set[v]=sn;
37             instack[v]=false;
38             s.pop();
39         }while(u!=v);
40         sort(group[sn].begin(),group[sn].end());
41         sn++;
42     }
43 }
44 int main()
45 {
46     while(~scanf("%d",&n))
47     {
48         for(int i=1;i<=n;i++)
49         {
50             for(int j=1;j<=n;j++)
51                 matrix[i][j]=false;
52         }
53         for(int i=1;i<=n;i++)
54         {
55             int m;
56             scanf("%d",&m);
57             for(int j=0;j<m;j++)
58             {
59                 int v;
60                 scanf("%d",&v);
61                 matrix[i][v]=true;
62                 arc[i].push_back(v+n);
63             }
64         }
65         for(int i=1;i<=n;i++)
66         {
67             int u;
68             scanf("%d",&u);
69             arc[u+n].push_back(i);
70         }
71         for(int i=1;i<=2*n;i++)
72             instack[i]=visited[i]=false;
73         sn=counter=0;
74         for(int i=1;i<=n;i++)
75         {
76             if(!visited[i])
77                 tarjan(i);
78         }
79         for(int i=1;i<=n;i++)
80         {
81             vector<int> ans;
82             for(int j=0;j<group[set[i]].size();j++)
83             {
84                 if(matrix[i][group[set[i]][j]-n])
85                     ans.push_back(group[set[i]][j]-n);
86             }
87             printf("%d",ans.size());
88             for(int j=0;j<ans.size();j++)
89                 printf(" %d",ans[j]);
90             printf("\n");
91             ans.clear();
92         }
93         for(int i=1;i<=2*n;i++)
94             arc[i].clear();
95         for(int i=0;i<sn;i++)
96             group[i].clear();
97     }
98     return 0;
99 }

?

轉載于:https://www.cnblogs.com/ZShogg/archive/2013/03/24/2978513.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/193016.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息