青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

oyjpArt ACM/ICPC算法程序設計空間

// I am new in programming, welcome to my blog
I am oyjpart(alpc12, 四城)
posts - 224, comments - 694, trackbacks - 0, articles - 6

PKU1904 king's quest

Posted on 2007-08-07 23:58 oyjpart 閱讀(2270) 評論(3)  編輯 收藏 引用 所屬分類: ACM/ICPC或其他比賽

King's Quest
Time Limit:15000MS  Memory Limit:65536K
Total Submit:938 Accepted:278
Case Time Limit:2000MS

Description
Once upon a time there lived a king and he had N sons. And there were N beautiful girls in the kingdom and the king knew about each of his sons which of those girls he did like. The sons of the king were young and light-headed, so it was possible for one son to like several girls.

So the king asked his wizard to find for each of his sons the girl he liked, so that he could marry her. And the king's wizard did it -- for each son the girl that he could marry was chosen, so that he liked this girl and, of course, each beautiful girl had to marry only one of the king's sons.

However, the king looked at the list and said: "I like the list you have made, but I am not completely satisfied. For each son I would like to know all the girls that he can marry. Of course, after he marries any of those girls, for each other son you must still be able to choose the girl he likes to marry."

The problem the king wanted the wizard to solve had become too hard for him. You must save wizard's head by solving this problem.

Input
The first line of the input contains N -- the number of king's sons (1 <= N <= 2000). Next N lines for each of king's sons contain the list of the girls he likes: first Ki -- the number of those girls, and then Ki different integer numbers, ranging from 1 to N denoting the girls. The sum of all Ki does not exceed 200000.

The last line of the case contains the original list the wizard had made -- N different integer numbers: for each son the number of the girl he would marry in compliance with this list. It is guaranteed that the list is correct, that is, each son likes the girl he must marry according to this list.

Output
Output N lines.For each king's son first print Li -- the number of different girls he likes and can marry so that after his marriage it is possible to marry each of the other king's sons. After that print Li different integer numbers denoting those girls, in ascending order.

Sample Input

4
2 1 2
2 1 2
2 2 3
2 3 4
1 2 3 4

 

Sample Output

2 1 2
2 1 2
1 3
1 4

 

Hint
This problem has huge input and output data,use scanf() and printf() instead of cin and cout to read data to avoid time limit exceed.

Source
Northeastern Europe 2003


題目給我們一個2*N個頂點的2分圖,并且給了一個完美匹配(Perfect Matching)以及每個頂點可以連接的其他的頂點。
題目要求是否可以確定某2個頂點連邊后,其他2*(N - 1)個頂點的2分圖是否可以構(gòu)成完美匹配。
分析:
題目給了你一個初始的最大匹配 怎樣用好這個匹配是非常關鍵的
首先把圖轉(zhuǎn)化成有向圖(因為后面我們要用到連通性判定)
現(xiàn)在令王子為A集合,公主為B集合
原圖中所有的邊轉(zhuǎn)化成A->B的邊 然后對原來的每一個匹配Ai->Bj 添加一條從Bj到Ai的邊
結(jié)論: 如果Ai,Bj能夠互訪 我們則認為Ai, Bj作為一條匹配邊仍然不會影響其他王子和自己心愛的人匹配
證明如下:
現(xiàn)在有一個匹配Ai->Bj 我們知道Ai和Bj可以互訪
我們要驗證其是否可以成立時對其他王子找MM沒有影響
1。如果題目中給的初始匹配包含這條邊 則題目給出的初始匹配就證明了這位王子的公德心
2。如果題目沒有給出這條邊 給出的是Ai -> Bk 由于Ai與Bk也可互訪 所以存在Bj->Ai->Bk的增廣路 也就是說可以建立另外一個匹配A?->Bk
所以同一個連通分量內(nèi)部是可以換匹配的 呵呵

關于求極大連通子圖的方法 具體如下:
求有向圖的極大強連通分支
1.對圖進行DFS遍歷 遍歷中記下所有的結(jié)束時間A[i].遍歷的結(jié)果是構(gòu)建的一座森林W1
  我們對W1中的每棵樹G進行步驟2到步驟3的操作
2.改變圖G中每一條邊的方向 構(gòu)造出新的有向圖Gr
3.按照A[i]由小到大的順序?qū)r進行DFS遍歷.遍歷的結(jié)果是構(gòu)建了新的樹林W2.
  W2中每棵樹上的頂點構(gòu)成了有向圖的極大強連通分支
如果對DFS的相關算法不熟悉 請參考我的另一篇文章
圖的DFS信息構(gòu)建+割點,橋,極大連通子圖三大法寶
http://www.shnenglu.com/sicheng/archive/2007/01/19/17767.html

如果覺得上面的方法太麻煩 還有一種簡單的方法(呵呵), 具體步驟如下:
我們定義定點U的標值函數(shù) LOW(U) = min { dfn(U), dfn(W) };
其中W是U或者U的后代點通過反向邊或者橫叉邊能夠到達的同一個連通分量的定點
dfn()是指一個點第一次被訪問的時間
由此可以看出 LOW(U)正是U所處的強連通分支中從U出發(fā)先通過樹枝邊(組成DFS樹的邊),前向邊,最后用后向邊或者橫叉邊到達的dfn的最小的定點的標值.而對于強分支的根Ri,顯然LOW(Ri) = dfn(Ri). 因此當深度有限搜索從一個使dfn = LOW的定點U返回時,從樹中移去根為U的所有頂點.每一個這種的集合是一個強分支.
算法的主要思路是逐步迭代算出LOW值:
當?shù)谝淮卧L問定點U時:
LOW(U) = Min(LOW(U), dfn(U))
后向邊(U,W)被檢查時:
LOW(U) = Min(LOW(U), dfn(W))
處于同一強分支的橫叉邊被檢查時:
LOW(U) = MIN(LOW(U), dfn(W))
檢查了U的兒子S的所有關聯(lián)邊后返回頂點U時:
LOW(U) = Min(LOW(U), LOW(S))

這樣就可以用一個DFS解決啦~ 

foj的一個"信與信封"的題目也可以用強連通來做 不過那個題目數(shù)據(jù)弱多了 枚舉+2分圖最大匹配也能過

下面這個程序是用第二種求法解決的:
Solution:
//by oyjpArt
 1#include <vector>
 2#include <algorithm>
 3using namespace std;
 4
 5const int N = 2010;
 6int nv, times, sccId;
 7int go[N], back[N]; //匹配的正向和反向
 8int low[N], dfn[N]; //low數(shù)組, dfn是第一次訪問某節(jié)點的時間
 9int love[N][N];  // love[i][j]代表i王子愛上j公主 即i向j連接一條邊
10int scc[N];   //scc代表強連通分量id (Strongly Connected Component ID)
11bool inS[N]; //inS代表是否在棧中(已被壓入且為被彈出) 注意 表示一個節(jié)點沒有被訪問過應該是dfn[i] == 0
12vector<int> S; //Stack
13
14#define Min(a, b) ((a) < (b) ? (a) : (b))
15
16void DFS(int x) {
17    int i;
18    dfn[x] = ++times; //第一次訪問
19    S.push_back(x); //壓入棧中
20    inS[x] = 1//標記入棧
21    int y = back[x], z; //找到相應王子
22    low[x] = times; //定義low[x]
23
24    for(i = 1; i <= love[y][0]; ++i) {
25        int j = love[y][i];
26        if(j != x) {
27            if(dfn[j] == 0) { //樹枝邊
28                DFS(j); 
29                low[x] = Min(low[x], low[j]); //檢查了x的兒子j的所有關聯(lián)邊后返回頂點x
30            }
31            else if(dfn[j] < dfn[x] && inS[j]) //處于同一強分支的后向邊或者橫叉邊被檢查
32                low[x] = Min(low[x], dfn[j]);
33        }
34    }
35
36    if(low[x] == dfn[x]) { //找到一個新的強連通分支
37        do {
38            z = S.back();
39            scc[z] = sccId; //標記連通分值 
40            inS[z] = false//出棧
41            S.pop_back();
42        }while(z != x); 
43        sccId++;
44    }
45}
46
47int main() {
48
49    scanf("%d"&nv);
50    int i, t, j;
51    for(i = 0; i < nv; ++i) {
52        scanf("%d"&love[i][0]);
53        for(j = 1; j <= love[i][0]; ++j) {
54            scanf("%d"&love[i][j]);
55            --love[i][j];
56        }
57    }
58    for(i = 0; i < nv; ++i) {
59        scanf("%d"&t);
60        go[i] = t-1;
61        back[t-1= i;
62    }
63
64    times = sccId = 0;
65    memset(inS, 0, sizeof(inS));
66    memset(dfn, 0, sizeof(dfn));
67    for(i = 0; i < nv; ++i) if(dfn[i] == 0) {
68        DFS(i); //對每個公主作DFS
69    }
70
71    for(i = 0; i < nv; ++i) {
72        vector<int> ans;
73        for(j = 1; j <= love[i][0]; ++j) {
74            if(scc[love[i][j]] == scc[go[i]]) //如果在同一個連通分量內(nèi)
75                ans.push_back(love[i][j]);
76        }
77        sort(ans.begin(), ans.end());
78        printf("%d", ans.size());
79        for(j = 0; j < ans.size(); ++j)
80            printf(" %d", ans[j]+1);
81        printf("\n");
82    }
83
84    return 0;
85}


下面這種求法是用第一種方法解決的
Solution:
//by oyjpArt
 1#include <vector>
 2#include <algorithm>
 3using namespace std;
 4
 5const int N = 2010;
 6int nv;
 7vector<int> head[N], head2[N], S;
 8int go[N], back[N]; 
 9int scc[N];
10bool chk[N];
11bool love[N][N];
12
13void DFS(int x) {
14    int i;
15    chk[x] = 1;
16    for(i = 0; i < head[x].size(); ++i) {
17        int j = back[head[x][i]];
18        if(!chk[j]) 
19            DFS(j);    
20    }
21    S.push_back(x); //入棧
22}
23
24void DFS2(int x, int id) {
25    int y = go[x], i;
26    chk[y] = 1;
27    scc[x] = id; //標記連通分支
28    for(i = 0; i < head2[y].size(); ++i) {
29        int j = go[head2[y][i]]; //找到對應的公主
30        if(!chk[j])
31            DFS2(head2[y][i], id);
32    }
33}
34
35int main() {
36    scanf("%d"&nv);
37    int i, t, u, j;
38    for(i = 0; i < nv; ++i) {
39        scanf("%d"&t);
40        while(t--) {
41            scanf("%d"&u);
42            love[i][u-1= 1;
43            head[i].push_back(u-1); //有向邊
44            head2[u-1].push_back(i); //逆轉(zhuǎn)的有向邊
45        }
46    }
47    for(i = 0; i < nv; ++i) {
48        scanf("%d"&t);
49        go[i] = t-1;
50        back[t-1= i;
51    }
52
53    memset(chk, 0, sizeof(chk));
54    for(i = 0; i < nv; ++i) if(!chk[i]) {
55        DFS(i); //對王子作DFS 確定i到達的點
56    }
57
58    memset(chk, 0, sizeof(chk));
59    int sccId = 0;
60    for(i = S.size()-1; i >= 0--i) {
61        int j = S[i];
62        if(!chk[go[j]]) {
63            DFS2(j, sccId); //再對公主做DFS 確定連通分支(對王子和對公主其實是一樣的 寫法有點不同而已:)
64            sccId++;
65        }
66    }
67
68    for(i = 0; i < nv; ++i) {
69        vector<int> ans;
70        for(j = 0; j < nv; ++j) if(love[i][j]) {
71            if(scc[i] == scc[back[j]])
72                ans.push_back(j);
73        }
74        sort(ans.begin(), ans.end());
75        printf("%d", ans.size());
76        for(j = 0; j < ans.size(); ++j)
77            printf(" %d", ans[j]+1);
78        printf("\n");
79    }
80
81    return 0;
82}

突然發(fā)現(xiàn)簡單的方法寫出來的程序還長一點點。。暈

Feedback

# re: PKU1904 king's quest  回復  更多評論   

2008-08-17 13:34 by sdfond
第二種思路很不錯,學習下。。。十分感謝!~

# re: PKU1904 king's quest  回復  更多評論   

2009-07-01 12:52 by WinterLegend
寫得不錯,贊一個。

# re: PKU1904 king's quest  回復  更多評論   

2009-07-02 20:54 by oyjpart
謝謝
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            牛牛精品成人免费视频| 欧美大片一区二区三区| 久久av一区二区| 狠狠色噜噜狠狠狠狠色吗综合| 欧美影院在线播放| 欧美国产乱视频| 欧美激情一区二区三区四区| 亚洲精品韩国| 久久午夜色播影院免费高清| 欧美中文字幕不卡| 久久综合导航| 亚洲视频在线免费观看| 国产一区二区主播在线| 欧美高清免费| 久久米奇亚洲| 香蕉成人啪国产精品视频综合网| 亚洲日韩视频| 欧美成人一区二免费视频软件| 亚洲福利在线观看| 免费欧美电影| 久久精品91久久久久久再现| 亚洲六月丁香色婷婷综合久久| 国产精品视频你懂的| 午夜精品视频在线观看| 在线综合亚洲| 亚洲深夜福利网站| 影音先锋在线一区| 久久性色av| 久久久99免费视频| 欧美在线视频一区二区三区| 午夜免费日韩视频| 欧美一级午夜免费电影| 欧美一区二区三区的| 亚洲欧美综合网| 性色av一区二区三区红粉影视| 国产精品久久久久久久浪潮网站 | 日韩一级大片| 日韩一二三区视频| 一区二区日韩欧美| 亚洲天堂av综合网| 亚洲欧美在线视频观看| 欧美亚洲综合网| 亚洲第一综合天堂另类专| 一区二区在线免费观看| 久久亚洲一区二区三区四区| 免费成人小视频| 国产永久精品大片wwwapp| 国产精品日韩高清| 国产一区二区按摩在线观看| 国内伊人久久久久久网站视频| 依依成人综合视频| 一区二区日韩伦理片| 欧美在线影院| 亚洲国产成人精品女人久久久 | 亚洲色图制服丝袜| 欧美怡红院视频| 欧美激情一区二区三区| 亚洲图片在区色| 一区二区三区欧美日韩| 久久香蕉国产线看观看av| 亚洲电影中文字幕| 午夜精品久久久久| 欧美一区二区| 欧美大片免费观看在线观看网站推荐| 一本大道久久a久久综合婷婷| 久久伊人免费视频| 免费在线亚洲欧美| 国产在线观看精品一区二区三区| 欧美区在线观看| 亚洲盗摄视频| 久久精品国产亚洲a| 亚洲小说欧美另类社区| 香蕉免费一区二区三区在线观看| 亚洲电影免费在线| 久久精品官网| 国产欧美婷婷中文| 亚洲午夜精品一区二区三区他趣| 美女日韩在线中文字幕| 亚洲无吗在线| 国产精品不卡在线| 亚洲最新合集| 亚洲精品免费在线| 日韩一二三区视频| 性做久久久久久免费观看欧美| 久久精品卡一| 亚洲免费一在线| 久久久久**毛片大全| 亚洲一二三区精品| 国产精品二区在线观看| 亚洲一级二级在线| 9色精品在线| 欧美午夜欧美| 欧美亚洲一区二区三区| 亚洲影院高清在线| 国产日韩欧美夫妻视频在线观看| 欧美亚洲免费高清在线观看| 欧美一区二区三区喷汁尤物| 在线中文字幕日韩| 欧美日韩免费在线观看| 正在播放欧美视频| 一区二区激情视频| 男人的天堂亚洲| 欧美不卡一卡二卡免费版| 亚洲美女性视频| 亚洲一区二区高清| 在线一区视频| 欧美激情精品久久久| 亚洲日本无吗高清不卡| 一本色道久久88综合日韩精品 | 宅男66日本亚洲欧美视频| 久久国产精品久久久| 欧美在线亚洲综合一区| 91久久久久久国产精品| 亚洲七七久久综合桃花剧情介绍| 欧美理论电影在线观看| 久久精品国产第一区二区三区| 亚洲国产清纯| 亚洲一区二区三区视频| 1024精品一区二区三区| 亚洲午夜久久久久久久久电影网| 国产在线不卡| 亚洲一区国产精品| 91久久黄色| 欧美一区二区免费观在线| 亚洲激情成人网| 午夜精品短视频| 欧美性猛交xxxx乱大交蜜桃| 欧美精品日韩综合在线| 99精品国产一区二区青青牛奶| 久久免费高清视频| 老色鬼精品视频在线观看播放| 欧美一区成人| 欧美精品97| 欧美岛国激情| 国语自产在线不卡| 亚洲免费中文| 午夜精品久久久99热福利| 欧美日韩国产一区精品一区| 欧美大片在线观看一区| 国产日韩精品一区二区浪潮av| 日韩一二在线观看| 中文无字幕一区二区三区| 欧美日本一道本| 亚洲人成在线观看| 亚洲全部视频| 欧美国产先锋| 亚洲国产一区二区在线| 亚洲国产欧美一区| 欧美大色视频| 亚洲精选中文字幕| 99热这里只有精品8| 欧美连裤袜在线视频| 国产日韩欧美在线一区| 蜜桃av一区二区在线观看| 国产真实乱偷精品视频免| 久久精品免费| 亚洲电影免费观看高清完整版在线观看 | 国产一区二区三区自拍| 性欧美xxxx大乳国产app| 久久国产精品电影| 在线不卡中文字幕| 免费一级欧美片在线观看| 亚洲欧洲日产国码二区| 亚洲小说区图片区| 国产欧美日韩综合一区在线观看| 香蕉久久一区二区不卡无毒影院| 国产精品高潮久久| 国产日本精品| 麻豆精品视频在线观看| 亚洲激情黄色| 国产精品毛片a∨一区二区三区| 久久国产夜色精品鲁鲁99| 亚洲国产1区| 亚洲欧美日韩在线一区| 激情欧美一区二区三区| 欧美日本在线播放| 性色一区二区| 日韩网站在线看片你懂的| 久久久噜噜噜久久| 中文av一区特黄| 亚洲国产91| 国产日韩欧美另类| 欧美福利视频网站| 久久成人精品视频| 久久精品电影| 亚洲人成人一区二区在线观看 | 国产亚洲毛片| 欧美精品一区视频| 亚洲永久免费观看| 欧美激情第一页xxx| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲天堂av在线免费| 亚洲精品资源美女情侣酒店| 国产主播一区二区| 狂野欧美激情性xxxx欧美| 狠狠干综合网| 黄色一区二区在线观看| 国产一区二区高清视频| 国产精品每日更新在线播放网址| 欧美国产日本|