uva 11324 The Largest Clique

  vjudge 上题目链接:uva 11324

  scc + dp,根据大白书上的思路:" 同一个强连通分量中的点要么都选,要么不选。把强连通分量收缩点后得到SCC图,让每个SCC结点的权等于它的结点数,则题目转化为求 SCC 图上权最大的路径。由于 SCC 图是一个 DAG, 可以用动态规划求解。"

  一开始我理解成了求所有结点的权值和,后来才明白所求的结果一定是 scc 上一条路径来的,即不能有任何分叉路径。我的代码如下:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<vector>
  5 using namespace std;
  6 const int N = 1003;
  7 
  8 vector<int> G[N], G2[N];
  9 bool vis[N];
 10 int sccno[N], scc_cnt, p[N];
 11 vector<int> S;
 12 
 13 void dfs(int x) {
 14     vis[x] = 1;
 15     for(int i = 0; i < G[x].size(); ++i)
 16         if(!vis[G[x][i]])   dfs(G[x][i]);
 17     S.push_back(x);
 18 }
 19 
 20 void dfs2(int x, int &num) {
 21     if(sccno[x])   return ;
 22     sccno[x] = scc_cnt;
 23     ++num;
 24     for(int i = 0; i < G2[x].size(); ++i)
 25         dfs2(G2[x][i], num);
 26 }
 27 
 28 void find_scc(int n) {
 29     memset(vis, 0, sizeof vis);
 30     S.clear();
 31     for(int i = 0; i < n; ++i)
 32         if(!vis[i])    dfs(i);
 33 
 34     memset(sccno, 0, sizeof sccno);
 35     memset(p, 0, sizeof p);
 36     scc_cnt = 0;
 37     for(int i = n - 1; i >= 0; --i)
 38         if(!sccno[S[i]]) {
 39             ++scc_cnt;
 40             int num = 0;
 41             dfs2(S[i], num);
 42             p[scc_cnt] = num;
 43         }
 44 }
 45 
 46 vector<int> d[N];
 47 void debug(int n) {
 48     for(int i = 0; i < n; ++i)
 49         d[i].clear();
 50     for(int i = 0; i < n; ++i)
 51         d[sccno[i]].push_back(i);
 52 
 53     for(int u = 1; u <= scc_cnt; ++u) {
 54         printf("sccno[%d]: ",u);
 55         for(int i = 0; i < d[u].size(); ++i)
 56             printf("%d ",d[u][i] + 1);
 57         printf(" num = %d  p[%d] = %d\n", d[u].size(), u, p[u]);
 58     }
 59 }
 60 
 61 
 62 vector<int> g3[N];
 63 int node(int x) {
 64     if(vis[x])  return p[x];
 65     vis[x] = 1;
 66     int Max = 0;
 67     for(int i = 0; i < g3[x].size(); ++i)
 68         Max = max(Max, node(g3[x][i]));
 69     return p[x] += Max;
 70 }
 71 
 72 void new_graph(int n) {
 73     for(int i = 0; i <= n; ++i)
 74         g3[i].clear();
 75     for(int u = 0; u < n; ++u)
 76     for(int i = 0; i < G[u].size(); ++i) {
 77         int v = G[u][i];
 78         if(sccno[u] != sccno[v])   g3[sccno[u]].push_back(sccno[v]);
 79     }
 80     memset(vis, 0, sizeof vis);
 81     int ans = 0;
 82     for(int i = 1; i <= scc_cnt; ++i)
 83         ans = max(ans, node(i));
 84     printf("%d\n",ans);
 85 }
 86 
 87 int main() {
 88     int t,n,m,x,y;
 89     scanf("%d",&t);
 90     while(t--) {
 91         scanf("%d %d",&n,&m);
 92         for(int i = 0; i < n; ++i) {
 93             G[i].clear();
 94             G2[i].clear();
 95         }
 96         while(m--) {
 97             scanf("%d %d",&x,&y);
 98             --x;   --y;
 99             G[x].push_back(y);
100             G2[y].push_back(x);
101         }
102         find_scc(n);
103 //        debug(n);
104         new_graph(n);
105     }
106     return 0;
107 }

 

posted @ 2015-08-28 16:31  Newdawn_ALM  阅读(141)  评论(0编辑  收藏  举报