Ponds

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 3234    Accepted Submission(s): 997

Problem Description
Betty owns a lot of ponds, some of them are connected with other ponds by pipes, and there will not be more than one pipe between two ponds. Each pond has a value v.

Now Betty wants to remove some ponds because she does not have enough money. But each time when she removes a pond, she can only remove the ponds which are connected with less than two ponds, or the pond will explode.

Note that Betty should keep removing ponds until no more ponds can be removed. After that, please help her calculate the sum of the value for each connected component consisting of a odd number of ponds

 
Input
The first line of input will contain a number T(1≤T≤30) which is the number of test cases.

For each test case, the first line contains two number separated by a blank. One is the number p(1≤p≤104) which represents the number of ponds she owns, and the other is the number m(1≤m≤105) which represents the number of pipes.

The next line contains p numbers v1,...,vp, where vi(1≤vi≤108) indicating the value of pond i.

Each of the last m lines contain two numbers a and b, which indicates that pond a and pond b are connected by a pipe.

 
Output
For each test case, output the sum of the value of all connected components consisting of odd number of ponds after removing all the ponds connected with less than two pipes.
 
Sample Input
1
7 7
1 2 3 4 5 6 7
1 4
1 5
4 5
2 3
2 6
3 6
2 7
 
Sample Output
21
 
题意:一直去度数小于1的点,直到不能再去。
 
题解:对图拓扑排序后,剩余部分DFS判断是否为奇数个,奇数个直接加权值。 坑点在下面标出。
 
 
#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include <vector>
using namespace std;
const int maxn = 1e4+;
vector<int> g[maxn];
int v[maxn];
int ans[maxn];
int vis[maxn];
int in[maxn]; int t;
int p,m;
int cnt;
void toposort()
{
queue<int> q;
for(int i = ; i<=p; i++)
if(in[i] <= ) //还有度数为0的点
q.push(i);
while(!q.empty())
{
int temp = q.front();
q.pop();
ans[temp]++;
for(int j = ; j<g[temp].size(); j++)
{
int vv = g[temp][j];
if(in[vv]<=) continue; //z这里有坑,否则就陷入死循环了。
in[vv]--;
if(in[vv] <= )
q.push(vv);
}
}
}
void dfs(int s,int& count,long long& sum)
{
if(ans[s]>||vis[s]) return;
vis[s] = ;
for(int i = ; i<g[s].size(); i++)
{
int vv = g[s][i];
if(ans[vv] == && !vis[vv])
{
count++;
sum += v[vv];
dfs(vv,count,sum);
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
memset(ans,,sizeof(ans));
memset(in,,sizeof(in));
memset(vis,,sizeof(vis));
scanf("%d %d",&p,&m);
for(int i = ; i<=p; i++)
{
scanf("%d",&v[i]);
}
int l,r;
for(int i = ; i<=p; i++) g[i].clear();
for(int i = ; i<=m; i++)
{
scanf("%d %d",&l,&r);
g[l].push_back(r);
g[r].push_back(l);
in[l]++;
in[r]++;
}
toposort();
long long sum = ,sum1 = ;
int count = ;
for(int i = ; i<=p; i++)
{
if(ans[i] == &&!vis[i])
{
sum1 = v[i];
count = ;
dfs(i,count,sum1);
if(count% == ) sum += sum1;
}
}
printf("%I64d\n",sum); }
return ;
}
/*
312
7 10
1 20 300 400 500 1000 5000
1 2
1 3
1 4
2 3
2 4
3 4
5 6
6 7
5 7
3 6 2 1
10 20
1 2 3 2
10 100 1000
1 2
1 3 3 1
10 100 1000
1 2
*/

HDU 5438 拓扑排序+DFS的更多相关文章

  1. ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083)-POJ1270)

    两道经典的同类型拓扑排序+DFS问题,第二题较第一题简单,其中的难点在于字典序输出+建立单向无环图,另外理解题意是最难的难点,没有之一... POJ1128(ZOJ1083)-Frame Stacki ...

  2. HDU 4857 拓扑排序 优先队列

    n个数,已经有大小关系,现给m个约束,规定a在b之前,剩下的数要尽可能往前移.输出序列 大小关系显然使用拓扑结构,关键在于n个数本身就有大小关系,那么考虑反向建图,优先选择值最大的入度为零的点,这样得 ...

  3. HDU 1811 拓扑排序 并查集

    有n个成绩,给出m个分数间的相对大小关系,问是否合法,矛盾,不完全,其中即矛盾即不完全输出矛盾的. 相对大小的关系可以看成是一个指向的条件,如此一来很容易想到拓扑模型进行拓扑排序,每次检查当前入度为0 ...

  4. 拓扑排序+DFS(POJ1270)

    [日后练手](非解题) 拓扑排序+DFS(POJ1270) #include<stdio.h> #include<iostream> #include<cstdio> ...

  5. hdu 4324 拓扑排序

    题意:给出一堆人的喜爱关系,判断有没有三角恋-_-|| 其实就是判断是否存在三条边的环. 一开始我是这么想的: 先拓扑排序,如果没有环那就直接No 如果有环?挑出环里的任意一个点(拓扑排序结束后不在拓 ...

  6. HDU 5638 拓扑排序+优先队列

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5638 题意: 给你一个DAG图,删除k条边,使得能个得到字典序尽可能小的拓扑排序 题解: 把拓扑排序 ...

  7. HDU 4324 (拓扑排序) Triangle LOVE

    因为题目说了,两个人之间总有一个人喜欢另一个人,而且不会有两个人互相喜欢.所以只要所给的图中有一个环,那么一定存在一个三元环. 所以用拓扑排序判断一下图中是否有环就行了. #include <c ...

  8. 拓扑排序-DFS

    拓扑排序的DFS算法 输入:一个有向图 输出:顶点的拓扑序列 具体流程: (1) 调用DFS算法计算每一个顶点v的遍历完成时间f[v] (2) 当一个顶点完成遍历时,将该顶点放到一个链表的最前面 (3 ...

  9. Ordering Tasks(拓扑排序+dfs)

    Ordering Tasks John has n tasks to do. Unfortunately, the tasks are not independent and the executio ...

随机推荐

  1. hdu_1072_Nightmare(BFS)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 题意:给你一个地图,让你在炸弹爆之前找到出口,最初炸弹设定为6,每走一格需要1,中途有地方能让炸 ...

  2. C++ 中 const和define的区别

    来源网址:http://wujiangping.blog.163.com/blog/static/195182011201255115125205/ 请区别用#define命令定义的符号常量和用con ...

  3. shell脚本学习(二)

    4.cat命令 1)  cat -s    摆脱多余的空白行 2)  cat -T    将制表符显示为^I 3)  cat -n    显示行号 4) cat -b    跳过空白行,然后显示行号 ...

  4. LD_LIBRARY_PATH vs LIBRARY_PATH

    LIBRARY_PATH is used by gcc before compilation to search for directories containing libraries that n ...

  5. how to increase an regular array length in java?

    Arrays in Java are of fixed size that is specified when they are declared. To increase the size of t ...

  6. 超赞!聊聊WEB APP、HYBRID APP与NATIVE APP的设计差异

    编者按:这3类主流应用你都了解吗?设计师除了要有视觉功夫,对不同形式的APP也应当了然于胸,今天百度的同学写了一篇非常全面的总结,帮你迅速搞定3类主流APP的设计方法,附带一大波避雷针,带你巧妙跳过A ...

  7. 百度前端面试题-类似slack的在线聊天室

    别人国庆出去玩,我在家写代码的感觉也是很不错哒. 首先介绍一下技术架构吧! 使用了js框架:FFF,zepto,jquery,md5.min.js 前端框架:Bootstrap 后端:野狗,部分PHP ...

  8. 剑指offer 二进制1中的个数

    算法-求二进制数中1的个数 问题描述 任意给定一个32位无符号整数n,求n的二进制表示中1的个数,比如n = 5(0101)时,返回2,n = 15(1111)时,返回4 这也是一道比较经典的题目了, ...

  9. android,view的执行过程onDraw、onSizeChanged,onFinishInflate

    小试view的执行过程,此是入门,高手绕道. ----------------------------------------------------------------------------- ...

  10. ios屏幕

    设备 屏幕尺寸 分辨率(pt) Reader 分辨率(px) 渲染后 PPI iPhone 3GS 3.5吋 320x480 @1x 320x480   163 iPhone 4/4s 3.5吋 32 ...