博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu5438(2015长春赛区网络赛1002)拓扑序+DFS
阅读量:6828 次
发布时间:2019-06-26

本文共 1819 字,大约阅读时间需要 6 分钟。

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

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

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
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
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<
<
View Code

 

转载于:https://www.cnblogs.com/cenariusxz/p/4806748.html

你可能感兴趣的文章