• hdu5438(2015长春赛区网络赛1002)拓扑序+DFS


    题意:给出一张无向图,每个节点有各自的权值,问在点数为奇数的圈中的点的权值总和是多少。

    通过拓扑序的做法标记出所有非圈上的点,做法就是加每条边的时候将两点的入度都加一,然后将所有度数为1的点入队,删去它的所有边,即对没条边连的点度数减一,度数减为1继续入队,直到队列为空,入过队列的点都进行标记,表示该点不在圈上,那么剩余没有标记的点一定要么在圈上、要么是单点或自环。这时候只要对于每个没有访问过的节点,DFS遍历它的连通区域,记录点数和权值和,如果点数为奇数,则统计权值和。但是注意如果只有一个点,不能算作一个圈,所以除了判断点数是否奇数,还需要判断点数大于1。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<math.h>
     5 #include<queue>
     6 #include<iostream>
     7 typedef long long ll;
     8 using namespace std;
     9 
    10 const int maxn=100050;
    11 const int maxm=200050;
    12 
    13 int head[maxn],point[maxm],nxt[maxm],id[maxn],size,vis[maxn];
    14 int v[maxn];
    15 int n,m;
    16 
    17 void init(){
    18     memset(head,-1,sizeof(head));
    19     size=0;
    20     memset(id,0,sizeof(id));
    21     memset(vis,0,sizeof(vis));
    22 }
    23 
    24 void add(int a,int b){
    25     point[size]=b;
    26     nxt[size]=head[a];
    27     head[a]=size++;
    28     id[b]++;
    29     point[size]=a;
    30     nxt[size]=head[b];
    31     head[b]=size++;
    32     id[a]++;
    33 }
    34 
    35 void topo(){
    36     queue<int>q;
    37     for(int i=1;i<=n;++i)if(id[i]==1){
    38         id[i]=-1;
    39         q.push(i);
    40     }
    41     while(!q.empty()){
    42         int u=q.front();
    43         q.pop();
    44         for(int i=head[u];~i;i=nxt[i]){
    45             int j=point[i];
    46             id[j]--;
    47             if(id[j]==1){
    48                 id[j]=-1;
    49                 q.push(j);
    50             }
    51         }
    52     }
    53 }
    54 
    55 int nnum=0;
    56 ll sum=0;
    57 
    58 void dfs(int s){
    59     vis[s]=1;
    60     nnum++;
    61     sum+=v[s];
    62     for(int i=head[s];~i;i=nxt[i]){
    63         int j=point[i];
    64         if(!vis[j]&&id[j]>0)dfs(j);
    65     }
    66 }
    67 
    68 int main(){
    69     int T;
    70     scanf("%d",&T);
    71     while(T--){
    72         scanf("%d%d",&n,&m);
    73         init();
    74         for(int i=1;i<=n;++i)scanf("%d",&v[i]);
    75         while(m--){
    76             int a,b;
    77             scanf("%d%d",&a,&b);
    78             add(a,b);
    79         }
    80         topo();
    81         ll ans=0;
    82         for(int i=1;i<=n;++i){
    83             if(!vis[i]&&id[i]>0){
    84                 sum=0;
    85                 nnum=0;
    86                 dfs(i);
    87                 if(nnum%2&&nnum>1)ans+=sum;
    88             }
    89         }
    90         cout<<ans<<endl;
    91     }
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    第二次冲刺周期站立会议(3)
    第二次冲刺周期站立会议(2)
    第二次冲刺周期站立会议(1)
    测试计划
    对各组第一次冲刺周期的评价
    团队绩效评估计划
    学校网站UI设计分析
    站立会议(10)
    Bower和Gulp集成前端资源
    Laravel的学习网站推荐
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4806748.html
Copyright © 2020-2023  润新知