HDOJ--1827--Summer Holiday(强连通分量的最小代价连接)
来源:互联网 发布:亿程旅行社 知乎 编辑:程序博客网 时间:2024/06/05 16:51
Summer Holiday
Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2368 Accepted Submission(s): 1108
Problem Description
To see a World in a Grain of Sand
And a Heaven in a Wild Flower,
Hold Infinity in the palm of your hand
And Eternity in an hour.
—— William Blake
听说lcy帮大家预定了新马泰7日游,Wiskey真是高兴的夜不能寐啊,他想着得快点把这消息告诉大家,虽然他手上有所有人的联系方式,但是一个一个联系过去实在太耗时间和电话费了。他知道其他人也有一些别人的联系方式,这样他可以通知其他人,再让其他人帮忙通知一下别人。你能帮Wiskey计算出至少要通知多少人,至少得花多少电话费就能让所有人都被通知到吗?
And a Heaven in a Wild Flower,
Hold Infinity in the palm of your hand
And Eternity in an hour.
—— William Blake
听说lcy帮大家预定了新马泰7日游,Wiskey真是高兴的夜不能寐啊,他想着得快点把这消息告诉大家,虽然他手上有所有人的联系方式,但是一个一个联系过去实在太耗时间和电话费了。他知道其他人也有一些别人的联系方式,这样他可以通知其他人,再让其他人帮忙通知一下别人。你能帮Wiskey计算出至少要通知多少人,至少得花多少电话费就能让所有人都被通知到吗?
Input
多组测试数组,以EOF结束。
第一行两个整数N和M(1<=N<=1000, 1<=M<=2000),表示人数和联系对数。
接下一行有N个整数,表示Wiskey联系第i个人的电话费用。
接着有M行,每行有两个整数X,Y,表示X能联系到Y,但是不表示Y也能联系X。
第一行两个整数N和M(1<=N<=1000, 1<=M<=2000),表示人数和联系对数。
接下一行有N个整数,表示Wiskey联系第i个人的电话费用。
接着有M行,每行有两个整数X,Y,表示X能联系到Y,但是不表示Y也能联系X。
Output
输出最小联系人数和最小花费。
每个CASE输出答案一行。
每个CASE输出答案一行。
Sample Input
12 162 2 2 2 2 2 2 2 2 2 2 2 1 33 22 13 42 43 55 44 66 47 47 127 88 78 910 911 10
Sample Output
3 6
Author
威士忌
思路:就是强连通然后连接强连通分量,找寻到一个最小代价,连通所有的强连通分量。
AC代码:
//两处错误,一处是tarjan算法中的栈定义在了函数内部。 //第二处错误是solve算法中vector应从j=0处开始遍历。 #include<stdio.h>#include<string.h>#include<stack>#include<algorithm>#include<vector>#define INF 0x3f3f3f#define MAX 1010*10 //关键还有MAX的大小的确定 using namespace std;struct node{//定义邻接表 int from,to,next;}edge[MAX];int head[MAX],low[MAX],dfn[MAX],cost[MAX];bool Instack[MAX];int in[MAX],edgenum;int scc_cnt,dfs_clock;int sccno[MAX];vector<int> NEW[MAX];//储存新图 vector<int>scc[MAX];//记录每个强连通内的点。 int n,m;stack<int>q;void init(){//初始化邻接表 edgenum=0;memset(head,-1,sizeof(head));}void addedge(int u,int v){node E={u,v,head[u]};edge[edgenum]=E;head[u]=edgenum++;}void getmap(){for(int i=1;i<=n;i++)scanf("%d",&cost[i]);for(int i=0;i<m;i++){int a,b;scanf("%d%d",&a,&b);addedge(a,b);}}void tarjan(int u){//寻找强连通分量 int v;low[u] = dfn[u] = ++dfs_clock;//更新初始化low和dfn数组 q.push(u);Instack[u] = true;for(int i = head[u]; i != -1; i = edge[i].next)//深搜每一个节点 {v = edge[i].to; if(!dfn[v]){tarjan(v);low[u] = min(low[u], low[v]);}else if(Instack[v])low[u] = min(low[u], dfn[v]); //构建反向边。 }if(low[u]==dfn[u]){//满足条件的话增加每一个强连通分量 scc_cnt++;scc[scc_cnt].clear(); while(1){v=q.top();sccno[v]=scc_cnt;scc[scc_cnt].push_back(v);q.pop();Instack[v]=false;if(u==v)//该强连通分量的所有点都出来的话 就跳出。 break;}}}void find_cut(){memset(low, 0, sizeof(low));//初始化寻找祖先的数组 memset(dfn, 0, sizeof(dfn));//初始化此时能遍历到的数组 memset(sccno, 0, sizeof(sccno));//初始化sccno数组,找到每个强连通的点。 memset(Instack, false, sizeof(Instack));dfs_clock = scc_cnt = 0;//初始化时间戳和强连通数量。 for(int i = 1; i <= n; i++)//遍历每一个节点 if(!dfn[i]) tarjan(i);}void suodian(){memset(in,0,sizeof(in));//初始化入度节点 for(int i=0;i<edgenum;i++){int u=sccno[edge[i].from];int v=sccno[edge[i].to];if(u!=v){//构建新图。 NEW[u].push_back(v);// 新图的边 in[v]++;// //新图中每个scc的入度。 }}}void solve(){int mincost=0,temp;//初始化mincost数值。 int cnt=0;if(scc_cnt==1){sort(cost+1,cost+n+1);printf("1 %d\n",cost[1]);}else{for(int i=1;i<=scc_cnt;i++){if(in[i])//入度为0的才需要构建新边 continue;cnt++;temp=INF;for(int j=0;j<scc[i].size();j++)//遍历的时候这一步是从0开始的 temp=min(cost[scc[i][j]],temp);//寻找到连接该强连通分量最小的代价 mincost+=temp;}printf("%d %d\n",cnt,mincost);}}int main(){while(scanf("%d%d",&n,&m)!=EOF){init();getmap();//输入地图 find_cut();//寻找强连通分量的数目。 suodian();//缩点,构造新图。 solve();//解决该问题。 }return 0;} //历时N天,终于总算是把这道题给解决了。心塞塞。无语了。心好累。
0 0
- HDOJ--1827--Summer Holiday(强连通分量的最小代价连接)
- 【强连通分量+缩点】 HDOJ 1827 Summer Holiday
- HDU 1827 Summer Holiday(强连通分量)
- HDU 1827 Summer Holiday(强连通分量)
- hdu 1827 summer holiday 强连通分量
- HDOJ 题目1827 Summer Holiday(强连通分量,缩点)
- hdu 1827 Summer Holiday (强连通分量)
- HDU 1827 Summer Holiday (强连通分量)
- HDU-1827-Summer Holiday(强连通分量)
- hdu 1827 Summer Holiday(强连通分量+缩点)
- HDU 1827 Summer Holiday (强连通分量+缩点)
- HDU - 1827 Summer Holiday(强连通分量+贪心)
- HDU 1827 Summer Holiday 强连通分量缩点
- hdu 1827 Summer Holiday 强连通分量缩点
- [HDU1827]Summer Holiday(Tarjan缩点+强连通分量)
- hdoj Summer Holiday 1827 (强连通分量 求最少连通多少点从而连通所有点) arjan求SCC+缩点 好题
- HDU 1827 Summer Holiday(强连通)
- HDU ACM 1827 Summer Holiday->强连通分量+缩点(tarjan算法)
- POJ 1144 Network (Tarjan求割点)
- poj 1422 Air Raid(最小路径覆盖)
- poj 3984 迷宫问题【BFS && DFS】【简单】
- js 实现倒计时
- iOS_ 摸推背景透明效果
- HDOJ--1827--Summer Holiday(强连通分量的最小代价连接)
- coreGraphics绘图
- spring获取数组参数(二)
- Cocos-2d js 多个精灵都调用同一个动作 执行不成功(加“.copy()“)
- 第12周-Microwave面板图形界面基础
- Joda-Time 简介
- 关于mfc 对powerpoint的操作,控制ppt播放
- 优化sql 语句的几种方式
- 在eclipse下android ndk直接编译librtmp。