HDOJ5438(图的各个连通分量遍历)
#include<cstdio> #include<cstring> using namespace std; const int MAX_N=100005; template<class T> struct Stack{ private: T a[MAX_N]; int top; public: Stack(){ top=0; } void Push(T x) { a[top++]=x; } T Pop() { return a[--top]; } bool isEmpty() { return top==0; } }; struct Edge{ int from,to,next; }edge[MAX_N]; int V,E; int val[MAX_N]; int d[MAX_N]; int head[MAX_N]; int vis[MAX_N]; int cnt; void addEdge(int u,int v) { Edge e={u,v,head[u]}; edge[cnt]=e; head[u]=cnt++; } void getMap() { cnt=0; memset(d,0,sizeof(d)); memset(head,-1,sizeof(head)); for(int i=0;i<E;i++) { int u,v; scanf("%d %d",&u,&v); addEdge(u,v); addEdge(v,u); d[u]++; d[v]++; } } void Clear() { memset(vis,0,sizeof(vis)); Stack<int> ss; for(int i=1;i<=V;i++) { if(d[i]<=1) { ss.Push(i); vis[i]=1; } } while(!ss.isEmpty()) { int x=ss.Pop(); for(int i=head[x];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!vis[v]&&--d[v]<=1) { ss.Push(v); vis[v]=1; } } } } int used[MAX_N]; long long sum; //int 会溢出 WA了多次 int num; void dfs(int u) { used[u]=1; if(d[u]>=2) { sum+=val[u]; num++; } for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!used[v]) { dfs(v); } } } long long ans;// int会溢出 void solve() { ans=0; Clear(); memset(used,0,sizeof(used)); for(int i=1;i<=V;i++) { sum=0; num=0; if(!used[i]) { dfs(i); if(num&1)//题目中odd是奇数的意思 ans+=sum; } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d %d",&V,&E); for(int i=1;i<=V;i++) { scanf("%d",&val[i]); } getMap(); solve(); printf("%lld\n",ans); } return 0; }