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

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

 #include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
using namespace std; const int maxn=;
const int maxm=; int head[][maxn],point[][maxm],nxt[][maxm],size[];
int n,t,scccnt,maxx;
int stx[maxn],low[maxn],scc[maxn];
int dp[maxn],id[maxn],vis[maxn];
stack<int>S; int max(int a,int b){return a>b?a:b;} void init(){
memset(head,-,sizeof(head));
size[]=size[]=;
memset(dp,,sizeof(dp));
memset(id,,sizeof(id));
maxx=;
} void add(int a,int b,int c=){
if(c){
for(int i=head[][a];~i;i=nxt[][i])if(point[][i]==b)return;
}
point[c][size[c]]=b;
nxt[c][size[c]]=head[c][a];
head[c][a]=size[c]++;
} void dfs(int s){
stx[s]=low[s]=++t;
S.push(s);
for(int i=head[][s];~i;i=nxt[][i]){
int j=point[][i];
if(!stx[j]){
dfs(j);
low[s]=min(low[s],low[j]);
}
else if(!scc[j]){
low[s]=min(low[s],stx[j]);
}
}
if(low[s]==stx[s]){
scccnt++;
while(){
int u=S.top();S.pop();
scc[u]=scccnt;
dp[scccnt]++;
if(s==u)break;
}
}
} void setscc(){
memset(stx,,sizeof(stx));
memset(scc,,sizeof(scc));
t=scccnt=;
for(int i=;i<n;++i)if(!stx[i])dfs(i);
for(int i=;i<n;++i){
for(int j=head[][i];~j;j=nxt[][j]){
int k=point[][j];
if(scc[i]!=scc[k]){
add(scc[i],scc[k],);
id[scc[k]]++;
}
}
}
} int Dp(int s){
int ans=;
vis[s]=;
for(int i=head[][s];~i;i=nxt[][i]){
if(!vis[point[][i]])ans+=Dp(point[][i]);
}
return ans+dp[s];
} int main(){
int T;
scanf("%d",&T);
for(int q=;q<=T;q++){
int m;
scanf("%d%d",&n,&m);
init();
while(m--){
int a,b;
scanf("%d%d",&a,&b);
add(b,a);
}
setscc();
for(int i=;i<=scccnt;++i)if(!id[i]){
memset(vis,,sizeof(vis));
dp[i]=Dp(i)-;
if(dp[i]>maxx)maxx=dp[i];
}
int ans=;
printf("Case %d: %d\n",q,maxx);
int cnt=;
for(int i=;i<n;++i){
if(!id[scc[i]]&&dp[scc[i]]==maxx){
if(cnt++)printf(" ");
printf("%d",i);
}
}
printf("\n");
}
return ;
}

hdu3639 强连通的更多相关文章

  1. 强连通 反向建图 hdu3639

    Hawk-and-Chicken Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. HDU5934 强连通分量

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5934 根据距离关系建边 对于强连通分量来说,只需引爆话费最小的炸弹即可引爆整个强连通分量 将所有的强连通分 ...

  3. POJ1236Network of Schools[强连通分量|缩点]

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16571   Accepted: 65 ...

  4. 有向图的强连通分量的求解算法Tarjan

    Tarjan算法 Tarjan算法是基于dfs算法,每一个强连通分量为搜索树中的一颗子树.搜索时,把当前搜索树中的未处理的结点加入一个栈中,回溯时可以判断栈顶到栈中的结点是不是在同一个强连通分量中.当 ...

  5. The Bottom of a Graph-POJ2553强连通

    The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9759 Accepted: 4053 ...

  6. Tarjan算法--强连通分量

    tarjan的过程就是dfs过程. 图一般能画成树,树的边有三种类型,树枝边 + 横叉边(两点没有父子关系) + 后向边(两点之间有父子关系): 可以看到只有后向边能构成环,即只有第三张图是强连通分量 ...

  7. bzoj 1051 (强连通) 受欢迎的牛

    题目:这里 题意: Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为 ...

  8. 强连通分量的一二三 | | JZOJ【P1232】 | | 我也不知道我写的什么

    贴题: 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间之 ...

  9. 有向图强连通分量的Tarjan算法

    有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...

随机推荐

  1. android asyncTask 详解

    只看http://www.cnblogs.com/xiaoluo501395377/p/3430542.html  足以

  2. 实现IOS圆角风格的列表ListView

    这段代码目前已经加在我的一个jar包androidkit中,还没发布. 适用于android1.6以上,不依赖其他jar包 使用时不需要继承这里的RoundListAdapter.只需要在你实现了Li ...

  3. C++学习之类的构造函数、析构函数

    在C++的类中,都会有一个或多个构造函数.一个析构函数.一个赋值运算操作符.即使我们自己定义的类中,没有显示定义它们,编译器也会声明一个默认构造函数.一个析构函数和一个赋值运算操作符.例如: //声明 ...

  4. Oracle GoldenGate 12c中的协同交付(Coordinated Delivery)

    OGG 12c中,并行交付有2种模式:集成交付.协同交付.不过集成交付只能针对目标端是oracle数据库(有版本要求)使用,而协同交付则可以在非oracle数据库上使用. 先来看2个问题, l 为什么 ...

  5. 嵌套遍历<s:iterator>map=new TreeMap(string,Map(string,User))

    //嵌套遍历,先给外层的map(假设是放在root中的,如果放在context的map中,要加#)取个别名,放到Actioncontext中 <s:iterator value="ma ...

  6. hdu 1069

    //Accepted 264 KB 0 ms //每种block只有三种方法,且每种放法至多放一次 //规定三条边的顺序后 //把所有的block按x递增排序,x相同则按y递增排序 //然后dp // ...

  7. Ubuntu 启动黑屏解决

    要sudo apt-get install xserver...................balabala...   then.... sudo gedit /boot/grub/grub.cf ...

  8. Android布局大全

    Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面. 所有的布局方式都可以归类为ViewGroup的 ...

  9. Cow Exhibition_背包(负数情况)

    Description "Fat and docile, big and dumb, they look so stupid, they aren't much fun..." - ...

  10. Candy Distribution_找规律

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6012   Accepted: 3341 Description N chi ...