hdu 3639 有向图缩点+建反向图+搜索
题意:给个有向图,每个人可以投票(可以投很多人,一次一票),但是一个人只能支持一人一次,支持可以传递,自己支持自己不算,被投支持最多的人。
开始想到缩点,然后搜索,问题是有一点想错了!以为支持按票数计算,而不是按人数!还各种树形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 有向图缩点+建反向图+搜索的更多相关文章
- hdu 3072 有向图缩点成最小树形图计算最小权
题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费.求最小费用. 有向图缩点(无需建立新图,,n<=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新 ...
- hdu 1827 有向图缩点看度数
题意:给一个有向图,选最少的点(同时最小价值),从这些点出发可以遍历所有. 思路:先有向图缩点,成有向树,找入度为0的点即可. 下面给出有向图缩点方法: 用一个数组SCC记录即可,重新编号,1.... ...
- HDU 3639 Hawk-and-Chicken(强连通分量+缩点)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013480600/article/details/32140501 HDU 3639 Hawk-a ...
- HDU 4635 (完全图 和 有向图缩点)
题目链接:HDU 4635 题目大意: 给你一个有向图,加有向边,使得这个图是简单有向图.问你最多加多少条有向边. 简单有向图: 1.不存在有向重边. 2.不存在图循环.(注意是不存在 “图” 循环 ...
- HDU 1045 Fire Net(行列匹配变形+缩点建图)
题意:n*n的棋盘上放置房子.同一方同一列不能有两个,除非他们之间被墙隔开,这种话. 把原始图分别按行和列缩点 建图:横竖分区.先看每一列.同一列相连的空地同一时候看成一个点,显然这种区域不可以同一时 ...
- HDU 3639 Hawk-and-Chicken(良好的沟通)
HDU 3639 Hawk-and-Chicken 题目链接 题意:就是在一个有向图上,满足传递关系,比方a->b, b->c,那么c能够得到2的支持,问得到支持最大的是谁,而且输出这些人 ...
- 对Tarjan——有向图缩点算法的理解
开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...
- hdu 4778 Gems Fight! 博弈+状态dp+搜索
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...
- hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
The King’s Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
随机推荐
- Codeforces Round #461 (Div. 2) D. Robot Vacuum Cleaner
D. Robot Vacuum Cleaner time limit per test 1 second memory limit per test 256 megabytes Problem Des ...
- Linux系统属性文件详解
1)inode概述 中文意思就是索引节点(index node)第一部分是inode 第二部分是block inode主要用来存放文件属性信息的(也就是ls - l 的结果)包含的属性信息包括文件的大 ...
- linux系统下单节点hadoop2的配置
Jdk安装: jdk-7u45-linux-x64.gz cp jdk-7u45-linux-x64.gz /usr/java/ cd /usr/java/ tar -zxvf jdk-7u45-li ...
- luogu1829 [国家集训队]Crash的数字表格
被 bs 了姿势水平--好好学习数学QAQQAQQAQ ref #include <iostream> #include <cstring> #include <cstd ...
- ckeditor添加日历控件
这里日历控件用的是开源的My97DatePicker,先看下效果图: 1.点击左侧自定义的日历控件按钮,弹出日历控件对话框. 2.点击确定,日历控件添加的表单设计器中,同时保留日历的控件样式 3.点击 ...
- ios开发学习笔记001-C语言基础知识
先来学习一下C语言基础知识,总结如下: 在xcode下编写代码. 1.编写代码 2.编译:cc –c 文件名.c 编译成功会生成一个 .o的目标文件 3.链接:把目标文件.o和系统自带的库合并在一起, ...
- c#中dynamic ExpandoObject的用法
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- [DM8168]Linux下控制GPIO实现LED流水灯
首先加载驱动模块,应用程序通过调用API实现GPIO控制功能. 驱动程序: /* * fileName: led_gpio.c * just for LED GPIO test * GP1_14 -& ...
- [转]/dev/null 命令用法
/dev/null :代表空设备文件 :代表重定向到哪里,例如:echo "123" > /home/123.txt 1 :表示stdout标准输出,系统默认值是1,所以&q ...
- maven国内镜像
<?xml version="1.0" encoding="UTF-8"?> <!--Licensed to the Apache Softw ...