hdu 5438 Ponds(toposort+DFS)

来源:互联网 发布:spss数据分析难吗 编辑:程序博客网 时间:2024/05/17 06:26

给一个无向图,将图中与其关联的边数小于2的点去掉,直到找不到这样的点为止,然后求奇块的权值和。


类似拓扑排序将度数小于2的点给去掉,然后剩下的点必然组成若干个圈,通过DFS标记边的同时统计顶点个数。若为奇块,累加权值即可。

注意数据范围啊。


#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<stack>#include<vector>#include<queue>using namespace std;typedef __int64 LL;#define maxn 10005struct Edge{    int to,next;}edge[200005];int head[maxn],a[maxn],cnt,deg[maxn];LL s,tot;inline void add(int u,int v){    edge[cnt].to=v;    edge[cnt].next=head[u];    head[u]=cnt++;}bool use[200005];void dfs(int u){    for(int i=head[u];~i;i=edge[i].next)    {        int v=edge[i].to;        if(use[i]||use[i^1]||!deg[v]) continue;        use[i]=use[i^1]=1;        ++tot;        s+=a[v];        deg[v]=0;        dfs(v);    }}int main(){    int n,m,T;    cin>>T;    while(T--)    {        scanf("%d%d",&n,&m);        for(int i=1;i<=n;++i) scanf("%d",&a[i]);        cnt=0;        memset(head,-1,sizeof(head));        memset(use,0,sizeof(use));        memset(deg,0,sizeof(deg));        for(int i=1;i<=m;++i)        {            int x,y;            scanf("%d%d",&x,&y);            add(x,y);            add(y,x);            ++deg[x];            ++deg[y];        }        queue<int> Q;        for(int i=1;i<=n;++i)            if(deg[i]==1) {                Q.push(i);                deg[i]=0;            }        while(!Q.empty())        {            int u=Q.front();Q.pop();            for(int i=head[u];~i;i=edge[i].next)            {                int v=edge[i].to;                if(deg[v]) --deg[v];                if(deg[v]==1){                    use[i]=use[i^1]=1;                    Q.push(v);                    deg[v]=0;                }            }        }        LL ans=0;        for(int i=1;i<=n;++i)            if(deg[i]){                s=a[i],tot=1;                deg[i]=0;                dfs(i);                if(tot&1) ans+=s;            }        printf("%I64d\n",ans);    }    return 0;}


0 0
原创粉丝点击