HDU 5438 Ponds(2015ACM/ICPC长春网络赛B)

来源:互联网 发布:udp编程bind函数的作用 编辑:程序博客网 时间:2024/05/29 14:02

【题目链接】http://acm.hdu.edu.cn/showproblem.php?pid=5438
【解题报告】
比赛的时候队友用并查集过的,对每个堆维护节点数量即可。但是比赛中对于删点操作调试了很久,最后还用了一个set来删边……
赛后看题解,领悟到可以维护一个队列来进行删点操作,队列中的点的度均小于等于1,每次取出一个点删掉,和它相邻的点如果度变成了1,那么把这个点压进队列里,直到队列为空。
之后跑一遍并查集或者bfs均可。

【参考代码】

#include<cstdio>#include<iostream>#include<vector>#include<queue>#include<cstring>using namespace std;int p,m;int v[10000+10],dep[10000+10];int vis[10000+10], vis2[10000+10];vector<int>G[10000+10];void del_point(){    queue<int>q;    for(  int i=1; i<=p; i++  ) if( dep[i]<=1 )   q.push( i );     while( !q.empty() )    {        int v=q.front();        vis[v]=1;        q.pop();        if(dep[v]==0)continue;        dep[v]--;        for(  int j=0; j<G[v].size(); j++ )if(  !vis[G[v][j]] )            {                  dep[G[v][j]]--;                  if(   dep[G[v][j]]<=1 ) q.push(  G[v][j]  );            }    }}long long bfs(  int rt  ){      queue<int>q;      int cnt=0;      long long tot=0;      q.push(rt);      vis2[rt]=1;      while(!q.empty())      {            int u=q.front();            cnt++;            tot+=v[u];            q.pop();            for(  int j=0; j<G[u].size(); j++  )if(  !vis[G[u][j]] && !vis2[G[u][j]]   )            {                  q.push(  G[u][j] );                  vis2[G[u][j]]=1;            }      }      if(cnt&1)return tot;      return 0;}int main(){    int T;    cin>>T;    while(T--)    {        memset( vis,0,sizeof(vis) );        memset( vis2,0, sizeof(vis2) );        memset(  dep,0,sizeof(dep) );            scanf("%d%d",&p,&m);            for(  int i=1;i<=p;i++ )G[i].clear();        for(int i=1;i<=p;i++)scanf("%d",&v[i]);        for( int i=1; i<=m;i++ )        {            int a,b;            scanf("%d%d",&a,&b);            G[a].push_back(b);            G[b].push_back(a);            dep[a]++; dep[b]++;        }        del_point();        long long ans=0;        for( int i=1;i<=p;i++ )if(  !vis[i] && !vis2[i]   )            {                  ans+=bfs( i  );            }            cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击