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

oyjpArt ACM/ICPC算法程序設(shè)計(jì)空間

// 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 閱讀(2269) 評(píng)論(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


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

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

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

這樣就可以用一個(gè)DFS解決啦~ 

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

下面這個(gè)程序是用第二種求法解決的:
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是第一次訪問(wèn)某節(jié)點(diǎn)的時(shí)間
 9int love[N][N];  // love[i][j]代表i王子愛(ài)上j公主 即i向j連接一條邊
10int scc[N];   //scc代表強(qiáng)連通分量id (Strongly Connected Component ID)
11bool inS[N]; //inS代表是否在棧中(已被壓入且為被彈出) 注意 表示一個(gè)節(jié)點(diǎn)沒(méi)有被訪問(wèn)過(guò)應(yīng)該是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; //第一次訪問(wèn)
19    S.push_back(x); //壓入棧中
20    inS[x] = 1//標(biāo)記入棧
21    int y = back[x], z; //找到相應(yīng)王子
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) { //樹(shù)枝邊
28                DFS(j); 
29                low[x] = Min(low[x], low[j]); //檢查了x的兒子j的所有關(guān)聯(lián)邊后返回頂點(diǎn)x
30            }
31            else if(dfn[j] < dfn[x] && inS[j]) //處于同一強(qiáng)分支的后向邊或者橫叉邊被檢查
32                low[x] = Min(low[x], dfn[j]);
33        }
34    }
35
36    if(low[x] == dfn[x]) { //找到一個(gè)新的強(qiáng)連通分支
37        do {
38            z = S.back();
39            scc[z] = sccId; //標(biāo)記連通分值 
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); //對(duì)每個(gè)公主作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]]) //如果在同一個(gè)連通分量?jī)?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; //標(biāo)記連通分支
28    for(i = 0; i < head2[y].size(); ++i) {
29        int j = go[head2[y][i]]; //找到對(duì)應(yīng)的公主
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); //對(duì)王子作DFS 確定i到達(dá)的點(diǎn)
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); //再對(duì)公主做DFS 確定連通分支(對(duì)王子和對(duì)公主其實(shí)是一樣的 寫(xiě)法有點(diǎn)不同而已:)
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)簡(jiǎn)單的方法寫(xiě)出來(lái)的程序還長(zhǎng)一點(diǎn)點(diǎn)。。暈

Feedback

# re: PKU1904 king's quest  回復(fù)  更多評(píng)論   

2008-08-17 13:34 by sdfond
第二種思路很不錯(cuò),學(xué)習(xí)下。。。十分感謝!~

# re: PKU1904 king's quest  回復(fù)  更多評(píng)論   

2009-07-01 12:52 by WinterLegend
寫(xiě)得不錯(cuò),贊一個(gè)。

# re: PKU1904 king's quest  回復(fù)  更多評(píng)論   

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>
            免费成人在线观看视频| 亚洲精品美女在线观看播放| 久久精品一区二区三区中文字幕 | 久久婷婷国产综合国色天香 | 久久亚洲春色中文字幕久久久| 欧美激情免费在线| 狠狠狠色丁香婷婷综合激情| 国产精品影视天天线| 国产区在线观看成人精品| 黑丝一区二区| 夜夜精品视频一区二区| 午夜伦理片一区| 女人天堂亚洲aⅴ在线观看| 亚洲国产清纯| 亚洲美洲欧洲综合国产一区| 亚洲免费人成在线视频观看| 久久久久www| 国产精品日韩电影| 亚洲黄色av| 久久久久一区二区三区四区| 国产一区二区成人久久免费影院| 亚洲第一精品影视| 欧美在线1区| 亚洲最黄网站| 欧美日韩三级在线| 亚洲精品一区二区在线| 久久性天堂网| 亚洲一区二区三区三| 欧美日韩色一区| 亚洲天堂av电影| 一本久久精品一区二区| 欧美视频在线看| 亚洲免费在线观看视频| 一本色道久久| 国产欧美日韩综合一区在线观看| 亚洲天堂男人| 亚洲女爱视频在线| 国产一区二区三区免费在线观看 | 亚洲欧洲精品一区二区三区波多野1战4 | 亚洲国产视频直播| 久久国产综合精品| 在线观看亚洲视频| 亚洲国产一区二区精品专区| 可以看av的网站久久看| 99re国产精品| 亚洲视频网站在线观看| 国产精品私拍pans大尺度在线 | 国产欧美一区二区精品婷婷| 欧美制服丝袜| 欧美国产在线电影| 亚洲欧美国产不卡| 美国成人直播| 欧美一区二区三区在线看| 久久久久久久久一区二区| 91久久久久久久久久久久久| 在线视频亚洲欧美| 最新日韩在线视频| 午夜国产不卡在线观看视频| 亚洲精品男同| 久久激情视频| 午夜在线a亚洲v天堂网2018| 欧美一区视频| 久久国产高清| 国产精品色午夜在线观看| 亚洲成人在线网站| 国产一区二区在线观看免费播放| 野花国产精品入口| 夜夜嗨av色综合久久久综合网| 久久青青草综合| 久久久噜噜噜久久中文字免| 国产欧美一区二区视频| 一区二区三区四区在线| 99国产精品国产精品毛片| 欧美88av| 亚洲久久一区| 亚洲视频一区在线观看| 欧美视频一区| 亚洲视频在线观看免费| 亚洲欧美在线免费| 国内精品久久久久久久影视蜜臀 | 欧美日韩在线播放一区二区| av成人天堂| 久久米奇亚洲| 亚洲精品欧洲| 国产精品爽爽爽| 欧美在线视频日韩| 亚洲人成人一区二区三区| 一本一本久久a久久精品综合麻豆| 欧美日韩精品国产| 亚洲一区二区免费看| 久久亚洲精品中文字幕冲田杏梨| 国内外成人在线| 女女同性女同一区二区三区91| 亚洲黄色成人久久久| 亚洲欧美日韩精品一区二区 | 亚洲欧洲三级| 国产精品综合av一区二区国产馆| 久久久久久伊人| 一区二区三区欧美日韩| 欧美激情第二页| 久久久久久久综合色一本| 一区二区三区.www| 亚洲精品久久久久久下一站| 国产在线乱码一区二区三区| 欧美连裤袜在线视频| 欧美大片91| 老司机午夜精品视频在线观看| 亚洲伊人观看| 午夜日韩视频| 欧美一区二区三区免费观看 | 亚洲欧美国产另类| 亚洲精品视频在线观看免费| 在线免费不卡视频| 欧美一区二区精品在线| 99综合精品| 亚洲视频二区| 欧美亚洲三区| 久久精品国产综合| 久久―日本道色综合久久| 欧美亚洲网站| 久久伊人亚洲| 欧美精品videossex性护士| 久色婷婷小香蕉久久| 欧美黑人一区二区三区| 欧美日韩国产综合视频在线观看中文 | 免费成人av在线| 欧美精品在线看| 国产精品久久久久aaaa九色| 国语自产精品视频在线看| 亚洲全黄一级网站| 欧美亚洲一区二区在线观看| 久久综合久色欧美综合狠狠| 亚洲欧洲综合| 欧美亚洲尤物久久| 欧美日本韩国| 亚洲激情亚洲| 欧美伊人久久| 日韩视频―中文字幕| 久久久人人人| 国产精品青草久久| 99精品欧美一区| 亚洲第一精品夜夜躁人人爽| 性欧美video另类hd性玩具| 国产精品va在线播放我和闺蜜| 亚洲日本成人女熟在线观看| 久久精品女人天堂| 亚洲欧美网站| 国产欧美精品va在线观看| 亚洲一区二区三区色| 一区二区三区产品免费精品久久75| 免费在线欧美黄色| 久久蜜臀精品av| 狠狠色综合色区| 欧美激情一区二区在线| 欧美~级网站不卡| 亚洲一区二区精品| 午夜精品久久久久久久99黑人| 国产精品毛片va一区二区三区 | 女女同性精品视频| 毛片一区二区三区| 欧美伊人影院| 久久精品免费观看| 美国十次了思思久久精品导航| 久久国产精品久久久久久| 久久久久久综合| 久久久国产成人精品| 亚洲欧美韩国| 久久综合九色九九| 欧美激情麻豆| 亚洲国产精品成人| 欧美黑人国产人伦爽爽爽| 香港成人在线视频| 欧美午夜片欧美片在线观看| 一区二区视频免费完整版观看| 久久精品国产96久久久香蕉| 欧美一区二区免费视频| 亚洲欧洲另类国产综合| 亚洲视频一二区| 最近看过的日韩成人| 中文精品99久久国产香蕉| 黄色成人在线网址| 艳妇臀荡乳欲伦亚洲一区| 在线观看日韩欧美| 欧美一区二区三区四区在线| 99这里有精品| 欧美成人精品一区二区| 久久久久久久久岛国免费| 欧美天堂亚洲电影院在线观看 | 性欧美video另类hd性玩具| 亚洲另类在线一区| 久热国产精品| 久久久精品欧美丰满| 国产精品欧美日韩一区二区| 亚洲三级电影在线观看| 91久久精品国产91久久性色tv| 午夜国产精品影院在线观看| 亚洲视频综合| 国产欧美婷婷中文| 久久久精品日韩欧美| 免费观看亚洲视频大全|