uestc 方老师和缘分

关于怎么建图,自己还真是想不出来。

我觉得就是找到每个方老师所在的scc里的所有缘分吧。。

转自http://www.cnblogs.com/whatbeg/p/3765621.html

做法:建图,每个方老师和它想要的缘分之间连一条有向边,然后,在给出的初始匹配中反向建边,即如果第i个方老师现在找到的是缘分u,则建边u->i。这样求出所有的强连通分量,每个强连通分量中方老师和缘分的数目一定是相等的,所以每个方老师一定可以找到与他在同一个强连通分量里的缘分,因为强连通分量中每个点都是可达的,某个方老师找到了其强连通分量中的非原配点,则该原配缘分一定可以在强连通分量中找到"新欢"。可以画个图看看。

由于要构造非二分图,缘分的编号从n+1开始,到2n。

uestc 方老师和缘分

  1 #include<iostream>

  2 #include<cstdio>

  3 #include<cstdlib>

  4 #include<cstring>

  5 #include<string>

  6 #include<queue>

  7 #include<algorithm>

  8 #include<map>

  9 #include<iomanip>

 10 #include<climits>

 11 #include<string.h>

 12 #include<cmath>

 13 #include<stdlib.h>

 14 #include<vector>

 15 #include<stack>

 16 #include<set>

 17 using namespace std;

 18 #define INF 1000000007

 19 #define MAXN 4010

 20 #define Mod 1000007

 21 #define N 100007

 22 #define NN 30

 23 #define sigma_size 3

 24 const int maxn = 6e5 + 10;

 25 using namespace std;

 26 typedef long long LL;

 27 const double pi = acos(-1);

 28 

 29 

 30 vector<int> G[MAXN];

 31 int dfn[MAXN], low[MAXN], instk[MAXN], sccno[MAXN], ans[MAXN];

 32 stack<int> S;

 33 int Time, cnt ,n, res;

 34 void Tarjan(int u)

 35 {

 36     dfn[u] = low[u] = ++Time;

 37     S.push(u);

 38     instk[u] = 1;

 39     for (int i = 0; i < G[u].size(); ++i) {

 40         int v = G[u][i];

 41         if (!dfn[v]) {

 42             Tarjan(v);

 43             low[u] = min(low[u], low[v]);

 44         }

 45         else if (instk[v]) {

 46             low[u] = min(low[u], dfn[v]);

 47         }

 48     }

 49     if (low[u] == dfn[u]) {

 50         cnt++;

 51         int v;

 52         do{

 53             v = S.top();

 54             S.pop();

 55             instk[v] = 0;

 56             sccno[v] = cnt;

 57         } while (v != u);

 58     }

 59 }

 60 

 61 void find_scc()

 62 {

 63     for (int i = 1; i <= n; ++i)

 64         if (!dfn[i]) Tarjan(i);

 65 }

 66 

 67 void init()

 68 {

 69     for (int i = 0; i <= n; ++i)

 70         G[i].clear();

 71     Time = cnt = 0;

 72     memset(dfn, 0, sizeof(dfn));

 73     memset(low, 0, sizeof(low));

 74     memset(sccno,0,sizeof(sccno));

 75     memset(instk, 0, sizeof(instk));

 76     while (!S.empty()) S.pop();

 77 }

 78 

 79 int main()

 80 {

 81     int k, u, v;

 82     while (~scanf("%d",&n)) {

 83         init();

 84         for (int i = 1; i <= n; ++i) {

 85             scanf("%d", &k);

 86             for (int j = 0; j < k; ++j) {

 87                 cin >> v;

 88                 G[i].push_back(v + n);

 89             }

 90         }

 91         for (int i = 1; i <= n; ++i) {

 92             scanf("%d", &v);

 93             G[v + n].push_back(i);

 94         }

 95         find_scc();

 96         for (int u = 1; u <= n; ++u) {

 97             k = 0;

 98             for (int i = 0; i < G[u].size(); ++i) {

 99                 v = G[u][i];

100                 if (sccno[u] == sccno[v])

101                     ans[k++] = v - n;

102             }

103             sort(ans, ans + k);

104             printf("%d", k);

105             for (int i = 0; i < k; ++i)

106                 printf(" %d",ans[i]);

107             puts("");

108         }

109     }

110     return 0;

111 }

 

你可能感兴趣的:(UE)