• hdu3639 强连通


    题意:有 n 个人,m 组支持关系,已知支持关系可以传递,比如 A 支持 B,则所有支持 A 的人也同时支持 B,问哪些人获得的支持数最多,最多获得多少支持(自己不能获得自己的支持)。

    首先,如果一些人他们互相支持,那么他们的支持数肯定都是一样的,所有支持他们其中一个人的也同时支持他们所有人,所以对于这些人我们可以强连通缩点。然后就获得了一个有向无环图,每个强连通分量有各自的人数。由于支持的人数可以传递,所以某个人支持了别人,那么他获得的支持数就一定不如他支持的人多,那么其实我们需要获得的就只是那些没有支持过别人的人,所以我们可以通过反向建图,那些没有支持别人的人就是入度为 0 的点,从每个这样的点开始DFS下去统计一共有多少个人是他能够到达的,然后再加上他自己的人数 - 1(不能获得自己的支持),这样我们再从中找出最大值以及这些人就行了。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stack>
      4 #include<queue>
      5 using namespace std;
      6 
      7 const int maxn=5005;
      8 const int maxm=30005;
      9 
     10 int head[2][maxn],point[2][maxm],nxt[2][maxm],size[2];
     11 int n,t,scccnt,maxx;
     12 int stx[maxn],low[maxn],scc[maxn];
     13 int dp[maxn],id[maxn],vis[maxn];
     14 stack<int>S;
     15 
     16 int max(int a,int b){return a>b?a:b;}
     17 
     18 void init(){
     19     memset(head,-1,sizeof(head));
     20     size[0]=size[1]=0;
     21     memset(dp,0,sizeof(dp));
     22     memset(id,0,sizeof(id));
     23     maxx=0;
     24 }
     25 
     26 void add(int a,int b,int c=0){
     27     if(c){
     28         for(int i=head[1][a];~i;i=nxt[1][i])if(point[1][i]==b)return;
     29     }
     30     point[c][size[c]]=b;
     31     nxt[c][size[c]]=head[c][a];
     32     head[c][a]=size[c]++;
     33 }
     34 
     35 void dfs(int s){
     36     stx[s]=low[s]=++t;
     37     S.push(s);
     38     for(int i=head[0][s];~i;i=nxt[0][i]){
     39         int j=point[0][i];
     40         if(!stx[j]){
     41             dfs(j);
     42             low[s]=min(low[s],low[j]);
     43         }
     44         else if(!scc[j]){
     45             low[s]=min(low[s],stx[j]);
     46         }
     47     }
     48     if(low[s]==stx[s]){
     49         scccnt++;
     50         while(1){
     51             int u=S.top();S.pop();
     52             scc[u]=scccnt;
     53             dp[scccnt]++;
     54             if(s==u)break;
     55         }
     56     }
     57 }
     58 
     59 void setscc(){
     60     memset(stx,0,sizeof(stx));
     61     memset(scc,0,sizeof(scc));
     62     t=scccnt=0;
     63     for(int i=0;i<n;++i)if(!stx[i])dfs(i);
     64     for(int i=0;i<n;++i){
     65         for(int j=head[0][i];~j;j=nxt[0][j]){
     66             int k=point[0][j];
     67             if(scc[i]!=scc[k]){
     68                 add(scc[i],scc[k],1);
     69                 id[scc[k]]++;
     70             }
     71         }
     72     }
     73 }
     74 
     75 int Dp(int s){
     76     int ans=0;
     77     vis[s]=1;
     78     for(int i=head[1][s];~i;i=nxt[1][i]){
     79         if(!vis[point[1][i]])ans+=Dp(point[1][i]);
     80     }
     81     return ans+dp[s];
     82 }
     83 
     84 int main(){
     85     int T;
     86     scanf("%d",&T);
     87     for(int q=1;q<=T;q++){
     88         int m;
     89         scanf("%d%d",&n,&m);
     90         init();
     91         while(m--){
     92             int a,b;
     93             scanf("%d%d",&a,&b);
     94             add(b,a);
     95         }
     96         setscc();
     97         for(int i=1;i<=scccnt;++i)if(!id[i]){
     98             memset(vis,0,sizeof(vis));
     99             dp[i]=Dp(i)-1;
    100             if(dp[i]>maxx)maxx=dp[i];
    101         }
    102         int ans=0;
    103         printf("Case %d: %d
    ",q,maxx);
    104         int cnt=0;
    105         for(int i=0;i<n;++i){
    106             if(!id[scc[i]]&&dp[scc[i]]==maxx){
    107                 if(cnt++)printf(" ");
    108                 printf("%d",i);
    109             }
    110         }
    111         printf("
    ");
    112     }
    113     return 0;
    114 }
    View Code
  • 相关阅读:
    数据库信息 (表名 行数 堆 集群 非聚集)的查询
    jquerygalleryview2.0 漂亮多样化的图片特效(多项自定义)
    枚举 EnumDescription 位运算 权限 sql c#
    vs2010缓存类
    透明遮罩层
    app_offline.htm的作用
    XmlToJSON(c#)
    jquery性能最佳实践
    .net面试问答(大汇总)
    apk反编译
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4813371.html
Copyright © 2020-2023  润新知