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. nefu 72 N!

    Description Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N! Input One N in one line, ...

  2. 第3章 Java语言基础----声明常量

    在程序运行过程中一直不会改变的量称为常量(constant),通常也被称为“final变量”: 声明常量的语句:final 数据类型 常量名[=值] 备注:1)常量名通常使用大写字母,但并不是必须的; ...

  3. JSP基本语法--Page指令 <%@page 属性=”内容“%>

    page指令语法:<%@page 属性=”内容“%> 常用:contentType,import,pageEncoding 例子,设置MIME属性,如果使用一些高版本的tomcat,可能自 ...

  4. reactor与proactor模式

    在比较这两个模式之前,我们首先的搞明白几个概念,什么是阻塞和非阻塞,什么是同步和异步. 同步和异步是针对应用程序和内核的交互而言的. 同步是指用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 ...

  5. 在ASP.Net中"../" "./" "~/"表示的意思

    "../" 相对当前(根据不同的语境,当前是不同的)的上一级目录"./" 就是当前目录 "~/" 当前项目的根路径,只在服务器端有效.

  6. mysql 连接两列

    以下划线符号,连接两列,作为查询结果: SELECT CONCAT(col_1,'_',col_2) FROM yourtable

  7. 上海赛趣-top.mainFrame.tabAddHandler方法详解

    top.mainFrame.tabAddHandler("item"+Id,'项目:'+itemname,'<%=basePath%>bizitem/goEditIte ...

  8. Notification使用笔记

    之前在项目中使用了Notification,现分享出来: checkNotification() function checkNotification(){ //判断是否支持Notification ...

  9. 解决centos无法上传文件和打开文件夹

    使用yum搭建了ftp服务..yum的使用参考:http://blog.csdn.net/enson16855/article/details/9140623 windows使用FileZilla连接 ...

  10. 使用runloop阻塞线程的正确写法

    使用runloop阻塞线程的正确写法 runloop可以阻塞线程,等待其他线程执行后再执行. 比如: @implementation ViewController{    BOOL end;}…– ( ...