题意:给个有向图,每个人可以投票(可以投很多人,一次一票),但是一个人只能支持一人一次,支持可以传递,自己支持自己不算,被投支持最多的人。

开始想到缩点,然后搜索,问题是有一点想错了!以为支持按票数计算,而不是按人数!还各种树形dp/搜索求可以到达边数。。提交WA了。。。

又反复读了题目之后才发现。。错误。。只要人数就行。。。问题简单了许多。。。

缩点成有向无环图后:每个SCC中支持的人数就是scc里面的人,要求可到达的点最多的点,当然要放过来求方便:反向图那个点可以到达的点最多!于是建反向图直接dfs即可,记录答案有点麻烦。。。提交就A了。。。这题总体花了我2多个小时。。算失败。。。

#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=5005,maxe=50005;
int nume=0;int head[maxv];int e[maxe][3];
void inline adde(int i,int j,int c)
{
e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
e[nume++][2]=c;
}
int dfn[maxv];int low[maxv];int vis[maxv];int ins[maxv]; stack<int>sta;
int scc[maxv];int numb=0;int times=0;
int n,m; int sccsize[maxv];
void tarjan(int u)
{
dfn[u]=low[u]=times++;
ins[u]=1;
sta.push(u);
for(int i=head[u];i!=-1;i=e[i][1])
{
int v=e[i][0];
if(!vis[v])
{
vis[v]=1;
tarjan(v);
if(low[v]<low[u])low[u]=low[v];
}
else if(ins[v]&&dfn[v]<low[u])
{
low[u]=dfn[v];
}
}
if(low[u]==dfn[u])
{
numb++;int counted=0;
int cur;
do
{
cur=sta.top();
sta.pop();
ins[cur]=0;
scc[cur]=numb;
counted++;
}while(cur!=u);
sccsize[numb]=counted;
}
}
struct pi
{
int id;
int w;
};
bool my (pi a,pi b)
{
if(a.w!=b.w)
return a.w>b.w;
else
return a.id<b.id;
}
int sums=0;
vector<vector<int> >e2(maxv+1);
int ind[maxv];
void dfs(int u)
{
for(int i=0;i<e2[u].size();i++)
{
int v=e2[u][i];
if(!vis[v])
{
vis[v]=1;
sums+=sccsize[v];
dfs(v);
}
}
}
vector<int>sumss;
void solve()
{
for(int i=0;i<n;i++)
{
if(!vis[i])
{
vis[i]=1;
tarjan(i);
}
}
for(int i=0;i<n;i++)
for(int j=head[i];j!=-1;j=e[j][1])
{
int v=e[j][0];
if(scc[i]!=scc[v])
{
e2[scc[v]].push_back(scc[i]);
ind[scc[i]]++;
}
}
int minsums=0;
vector<pi>ans;
for(int i=1;i<=numb;i++)
{
sums=0;
memset(vis,0,sizeof(vis));
if(ind[i]==0)
{
vis[i]=1;
sums+=sccsize[i]-1;
dfs(i);
if(sums>=minsums)
{
pi tp;
tp.w=sums;
tp.id=i;
ans.push_back(tp);
minsums=sums;
}
}
}
vector<int>realans;
for(int i=0;i<ans.size();i++)
{
if(ans[i].w==minsums)
{
realans.push_back(ans[i].id);
}
}
for(int j=0;j<realans.size();j++)
for(int i=0;i<n;i++)
{
if(scc[i]==realans[j])
{
sumss.push_back(i);
}
}
sort(sumss.begin(),sumss.end());
printf("%d\n",minsums);
for(int i=0;i<sumss.size();i++)
{
if(i!=sumss.size()-1)
printf("%d ",sumss[i]);
else
printf("%d\n",sumss[i]);
}
}
void read_build()
{
int aa,bb,cc;
for(int i=0;i<m;i++)
{
scanf("%d%d",&aa,&bb);
adde(aa,bb,0);
}
}
void init()
{
numb=times=nume=0;
sumss.clear();
for(int i=0;i<maxv;i++)
{
head[i]=-1;
ins[i]=dfn[i]=low[i]=scc[i]=vis[i]=0;
sccsize[i]=0;
ind[i]=0;
e2[i].clear();
}
}
int main()
{
int T;
scanf("%d",&T);
int ct=1;
while(T--)
{
scanf("%d%d",&n,&m);
init();
read_build();
printf("Case %d: ",ct++);
solve();
}
return 0;
}

hdu 3639 有向图缩点+建反向图+搜索的更多相关文章

  1. hdu 3072 有向图缩点成最小树形图计算最小权

    题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费.求最小费用. 有向图缩点(无需建立新图,,n<=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新 ...

  2. hdu 1827 有向图缩点看度数

    题意:给一个有向图,选最少的点(同时最小价值),从这些点出发可以遍历所有. 思路:先有向图缩点,成有向树,找入度为0的点即可. 下面给出有向图缩点方法: 用一个数组SCC记录即可,重新编号,1.... ...

  3. HDU 3639 Hawk-and-Chicken(强连通分量+缩点)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013480600/article/details/32140501 HDU 3639 Hawk-a ...

  4. HDU 4635 (完全图 和 有向图缩点)

    题目链接:HDU  4635 题目大意: 给你一个有向图,加有向边,使得这个图是简单有向图.问你最多加多少条有向边. 简单有向图: 1.不存在有向重边. 2.不存在图循环.(注意是不存在 “图” 循环 ...

  5. HDU 1045 Fire Net(行列匹配变形+缩点建图)

    题意:n*n的棋盘上放置房子.同一方同一列不能有两个,除非他们之间被墙隔开,这种话. 把原始图分别按行和列缩点 建图:横竖分区.先看每一列.同一列相连的空地同一时候看成一个点,显然这种区域不可以同一时 ...

  6. HDU 3639 Hawk-and-Chicken(良好的沟通)

    HDU 3639 Hawk-and-Chicken 题目链接 题意:就是在一个有向图上,满足传递关系,比方a->b, b->c,那么c能够得到2的支持,问得到支持最大的是谁,而且输出这些人 ...

  7. 对Tarjan——有向图缩点算法的理解

    开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...

  8. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  9. hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. 第37课 thinkphp5添加商品基本信息及通过前置钩子上传商品主图 模型事件(勾子函数)

    目录 手册地址: before_insert(新增之前的操作) 要实现的功能 思路 触发条件: 1. 控制器里必须要调用模型的save()方式保存数据,用insert()触发不了勾子函数的 2. 模型 ...

  2. 模块numpy的用法

    https://blog.csdn.net/qq351469076/article/details/78817378 机器学习三剑客之Numpy: https://www.jianshu.com/p/ ...

  3. vim 命令总结

    命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim ...

  4. kettle - Linux下定时执行kettle作业

    Linux下实现kettle 自动同步数据 1.安装jdk tar -zxvf jdk-7u25-linux-x64.tar.gz -C /usr/share 2.配置java环境 vim /etc/ ...

  5. oracle 11g 版本自带移除,省时省力

    ---oracle删除 app\Administrator\product\11.2.0\dbhome_1\deinstall.bat 指定要取消配置的所有单实例监听程序 [LISTENER]: En ...

  6. MOCTF-火眼金睛

    MOCTF-火眼金睛 http://119.23.73.3:5001/web10/ 把这个题目当作python爬虫来练习. 首先要获取到文本框里面的全部信息, import requests impo ...

  7. Python/PHP 远程文件/图片 下载

    php 实现远程图片下载并保存到本地 /* *功能:php完美实现下载远程图片保存到本地 *参数:文件url,保存文件目录,保存文件名称,使用的下载方式 *当保存文件名称为空时则使用远程文件原来的名称 ...

  8. linux命令之grep、cut

    输入: ifconfig eth0 eth0表示主机的第一块网卡. 输出: eth0: flags=<UP,BROADCAST,RUNNING,MULTICAST> mtu inet 19 ...

  9. 聊聊、Java 命令 第一篇

    网上很多讲 Javac 和 Java 命令的,我觉得还是要自己写一写,做一个自己的总结,也方便以后查询. 开始之前先看看 help 命令,基本上任何一个软件都会提供这个命令. 没有什么比 -help ...

  10. python 文件(file)操作

    操作文件的一般流程有: 打开文件.文件处理.关闭文件 开开文件的模式有: r,只读模式(默认). w,只写模式.[不可读:不存在则创建:存在则删除内容:] a,追加模式.[不可读: 不存在则创建:存在 ...