网址:http://acm.hdu.edu.cn/showproblem.php?pid=5438

Ponds

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 376    Accepted Submission(s): 116

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
 
Source
 
Recommend
hujie   |   We have carefully selected several similar problems for you:  5449 5448 5447 5446 5445

将孩子个数小于等于1的点进入队列,修改与该点相连的孩子数目,维护队列,最后通过dfs查看每一堆池塘的数目,奇数加,偶数忽略。。。

思路好像很行,不过还是在开始的时候理解错了题意了,当时不太懂 odd number of ponds是什么意思,所以开始的时候没有dfs

真的该祭奠一下我的时间了啊,结束前开了好几发,但是一直返回WR,之后改的成了RE了,不知道原因,果然最后就把这个题掉了

结束后开始一点点找错,因为代码太乱了,所以就压根没有发现什么错误,之后再PS的帮助下发现了两个可耻的错误,开始的RE是因为入队之后删边的时候用的是队列里的当前点的孩子数目,结果这个数目可能在入队之后修改了(因为判断完之后就会改变数组节点中的值了),实际上可能不再有边了,这样result可能返回的是end(),所以在删除的时候erase(end())肯定就出错了

另外一个就更SB了,最后dfs图的时候竟然把n用成m了,这能对吗。。。

错误代码:

#pragma comment(linker, "/STACK:102400000000,102400000000")
#include<iostream>
#include<stdio.h>
#include<math.h>
#include <string>
#include<string.h>
#include<map>
#include<queue>
#include<set>
#include<utility>
#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define eps 1e-8
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define ll long long int
#define mod 1000000007
#define maxn 1005
#define maxm 1000005
int point[10005];
struct T{
int childnum;
int i;
int mark;
vector <int> vec;
friend bool operator < (T n1, T n2)
{
return n1.childnum > n2.childnum;
}
}node[10005]; bool vis[10005];
int cnt=0;
long long tsum=0;
void dfs(int x){
if(vis[x]==true) return ;
cnt++,tsum += point[ x ];
vis[x]=true;
for(int i=0;i<node[x].childnum;i++)
dfs( node[x].vec[i] );
} int main (){
int Case;
rd(Case);
while(Case--){
memset(vis,0,sizeof(vis));
int n,m,temp1,temp2;
ll sum=0;
vector<int>::iterator result;
rd2(n,m);
for(int i=1;i<=n;i++) node[i].childnum=0,node[i].i=i,node[i].mark=0 ,node[i].vec.clear();
for(int i=1;i<=n;i++){
rd(point[i]);
sum+=point[i];
}
for(int i=0;i<m;i++){
rd2(temp1,temp2);
//bool mark = (find( node[temp1].vec.begin(), node[temp1].vec.end(), temp2 ) == node[temp1].vec.end() ); if(temp1!=temp2){
node[temp1].vec.push_back(temp2);
node[temp1].childnum++;
node[temp2].vec.push_back(temp1);
node[temp2].childnum++;
}
}
priority_queue <T> que;
for(int i=1;i<=n;i++)
if(node[i].childnum<=1){
que.push(node[i]);
node[i].mark=1;
sum-=point[i];
}
//cout<<"***"<<endl;
while(!que.empty()){
// cout<<"&&&"<<que.top().i<<endl;
if(que.top().childnum==1){ //修改为 : node[que.top().i].childnum==1
int x=que.top().vec[0];//cout<<x<<endl;
result = find( node[x].vec.begin(), node[x].vec.end(), que.top().i );
node[x].vec.erase(result);
node[x].childnum--; int i = que.top().i ;
node[i].vec.erase(node[i].vec.begin());
node[i].childnum-- ; if(node[x].childnum<=1 && node[x].mark == 0){
que.push(node[x]);
node[x].mark=1;
sum-=point[x];
}
}
que.pop();
}
for(int i=1;i<=m;i++){ ///修改为 : i<=n
tsum=cnt=0;
if(!vis[i] && node[i].childnum>=1 ){
dfs(i);
if( cnt%2==0 )
sum-=tsum;
}
// cout<<endl;
}
printf("%I64d\n",sum);
} return 0 ;
}

其实当时没有做出来一点都不冤,因为之后看自己的代码简直就是一坨屎,思路根本不清晰,所以导致有点思路之后敲代码还是有点一头雾水,所以以后还是有了思路之后,最起码是能整体的脉络差不多清晰了再敲。

#pragma comment(linker, "/STACK:102400000000,102400000000")
#include<iostream>
#include<stdio.h>
#include<math.h>
#include <string>
#include<string.h>
#include<map>
#include<queue>
#include<set>
#include<utility>
#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define eps 1e-8
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define ll long long int int point[10005];
vector <int> vec[10005];
bool vis[10005];
bool inqueue[10005];
int cnt=0;
long long tsum=0; void dfs(int x)
{
if(vis[x]) return ;
cnt++,tsum += point[ x ],vis[x]=true;
for(int i=0; i<vec[x].size(); i++)
dfs( vec[x][i] );
} void addedge(int temp1,int temp2)
{
vec[temp1].push_back(temp2);
vec[temp2].push_back(temp1);
} int main ()
{
int Case;
rd(Case);
while(Case--)
{
memset(vis,0,sizeof(vis));
memset(inqueue,0,sizeof(inqueue));
int n,m,temp1,temp2;
ll sum=0;
vector<int>::iterator result;
rd2(n,m);
for(int i=1; i<=n; i++)
{
vec[i].clear();
rd(point[i]);
sum+=point[i];
}
for(int i=0; i<m; i++)
{
rd2(temp1,temp2);
addedge(temp1,temp2);
} queue <int> que; ///没必要将点放入队列 建立索引关系就行
for(int i=1; i<=n; i++)
if(vec[i].size()<=1)
{
que.push(i);
vis[i]=true,inqueue[i]=1,sum-=point[i];
} while(!que.empty())
{
if( vec[que.front()].size()==1 )
{
int x=vec[que.front()][0];
result = find( vec[x].begin(), vec[x].end(), que.front() );
vec[x].erase(result); vec[que.front()].clear(); ///将队列中仅有一个元素清空 if(vec[x].size()<=1 && inqueue[x] == 0)
{
que.push(x);
inqueue[x]=1,vis[x]=true,sum-=point[x];
}
}
que.pop();
} for(int i=1; i<=n; i++){
tsum=cnt=0;
if( !vis[i] ){
dfs(i);
if( cnt%2==0 )
sum-=tsum;
}
}
printf("%I64d\n",sum);
} return 0 ;
}

其实在遍历队列中的元素的时候根本没有必要删除边的关系,因为已经在入队的时候为之后的dfs做准备了,只要入队之后便不再遍历了,删除边就没什么用了,只是更改vec[i]中的数目就可以了...

其实开始的思路清晰的话肯定早就A掉了,以后注意。。。

Regional Changchun Online--Ponds的更多相关文章

  1. 2015ACM/ICPC Asia Regional Changchun Online /HDU 5438 图

    Ponds                                   Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 1310 ...

  2. 2013 Asia Regional Changchun C

    Little Tiger vs. Deep Monkey Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K ( ...

  3. Regional Changchun Online--Elven Postman(裸排序二叉树)

    Elven Postman Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Tot ...

  4. Regional Changchun Online--Travel(最小生成树&& 并查集)

    Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  5. Regional Changchun Online--Alisha’s Party

    Alisha's Party Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  6. hdu 5444 Elven Postman(二叉树)——2015 ACM/ICPC Asia Regional Changchun Online

    Problem Description Elves are very peculiar creatures. As we all know, they can live for a very long ...

  7. (并查集)Travel -- hdu -- 5441(2015 ACM/ICPC Asia Regional Changchun Online )

    http://acm.hdu.edu.cn/showproblem.php?pid=5441 Travel Time Limit: 1500/1000 MS (Java/Others)    Memo ...

  8. (二叉树)Elven Postman -- HDU -- 54444(2015 ACM/ICPC Asia Regional Changchun Online)

    http://acm.hdu.edu.cn/showproblem.php?pid=5444 Elven Postman Time Limit: 1500/1000 MS (Java/Others)  ...

  9. 2015 ACM/ICPC Asia Regional Changchun Online HDU 5444 Elven Postman【二叉排序树的建树和遍历查找】

    Elven Postman Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

随机推荐

  1. Jenkins入门系列之

    Jenkins入门系列之——00答疑解惑 Jenkins进阶系列之——11修改Jenkins用户的密码 Jenkins进阶系列之——12详解Jenkins节点配置 Jenkins进阶系列之——13修改 ...

  2. com.opensymphony.module.sitemesh.filter.PageFilter 装饰页面

    1.web.xml中配置: <filter> <filter-name>sitemeshFilter</filter-name> <filter-class& ...

  3. get跟post编码--转

    1.Get是用来从服务器上获得数据(没有请求体),而Post是用来向服务器上传递数据(包含请求体). 2.Get将表单中数据的按照variable=value的形式,添加到action(服务)所指向的 ...

  4. 一个项目中说系统分为表现层、控制层、逻辑层、DAO层和最终数据库五层架构-转

    表现层就是看到的东西,比如你现在看到的当前页面控制层就将你的请求从页面传到后台代码逻辑层就是处理你的请求的代码DAO层就是将数据存到数据库中的代码数据库就是数据库了,存东西用的 ,DAO层就是将访问数 ...

  5. SQL SERVER 生成建表脚本

    /****** Object: StoredProcedure [dbo].[GET_TableScript_MSSQL] Script Date: 06/15/2012 11:59:00 ***** ...

  6. java中字符串的非空判断

    问题如下:在java 中 字符串为null 如何判断String str;if(str==null) ??str.equal("null") ?? 答:我觉得应该搞清楚字符串对象和 ...

  7. SSL使用windows证书库中证书实现双向认证

    前一段时间对OpenSSL库中的SSL通讯稍微琢磨了一下,在百度文库中找了个示例程序,然后在机器上跑,哇塞,运行成功!那时那个惊喜啊,SSL蛮简单的嘛.前几天,老板要我整一个SSL通讯,要使用wind ...

  8. 【性能测试】性能测试总结<一>

    目录: 一. 什么是软件性能 二.不同群体眼中的性能 三.性能测试类型 四.性能测试应用场景 五.性能测试基本概念 正文: 一. 什么是软件性能 定义:软件的性能是软件的一种非功能特性,它关注的不是软 ...

  9. SQL SERVER 2008安装时出现不能在控件上调用 Invoke 或 BeginInvoke错误 解决方法

    或者 SQL SERVER 2008安装时要求重启,但重启后仍要求重启.都可以使用此方法. 注册表的 "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet ...

  10. SPOJ #453. Sums in a Triangle (tutorial)

    It is a small fun problem to solve. Since only a max sum is required (no need to print path), we can ...