网址:http://acm.hdu.edu.cn/showproblem.php?pid=5438
1 7 7 1 2 3 4 5 6 7 1 4 1 5 4 5 2 3 2 6 3 6 2 7
21
将孩子个数小于等于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 ; }
其实开始的思路清晰的话肯定早就A掉了,以后注意。。。