HDU2242 考研路茫茫——空调教室(tarjan+树形DP)
http://acm.hdu.edu.cn/showproblem.php?pid=2242
很好的题目
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #define inf (1<<30) #define nMAX 10005 #define mMAX 20010 using namespace std; int dfn[nMAX],low[nMAX],belon[nMAX],sta[nMAX],top,times,atype; int s_edge,s_edge2,head[nMAX],head2[nMAX]; int n,num1[nMAX],num2[nMAX],SUM,ans; struct Edge { int v,nxt; }edge[2*mMAX],edge2[2*mMAX]; void addedge(int u,int v) { s_edge++; edge[s_edge].v=v; edge[s_edge].nxt=head[u]; head[u]=s_edge; } void addedge2(int u,int v) { s_edge2++; edge2[s_edge2].v=v; edge2[s_edge2].nxt=head2[u]; head2[u]=s_edge2; } void tarjan(int u,int fa) { int fg=0; dfn[u]=low[u]=++times; sta[++top]=u; for(int e=head[u];e;e=edge[e].nxt) { int v=edge[e].v; if(!fg&&v==fa) {fg=1;continue;} if(!dfn[v]) { tarjan(v,u); low[u]=min(low[u],low[v]); } else low[u]=min(low[u],dfn[v]); } int j; if(dfn[u]==low[u]) { atype++; do{ j=sta[top--]; belon[j]=atype; num2[atype]+=num1[j]; }while(j!=u); } } int dfs(int u,int pre) { int sum=num2[u]; for(int e=head2[u];e;e=edge2[e].nxt) { int v=edge2[e].v; if(v==pre) continue; sum+=dfs(v,u); } int t=abs(SUM-2*sum); ans=min(ans,t); return sum; } void init() { memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(num2,0,sizeof(num2)); top=0; times=0; atype=0; } int main() { int i,j,m; while(~scanf("%d%d",&n,&m)) { SUM=0; for(i=0;i<n;i++) {scanf("%d",&num1[i]);SUM+=num1[i];} memset(head,0,sizeof(head)); s_edge=0; while(m--) { scanf("%d%d",&i,&j); addedge(i,j); addedge(j,i); } init(); tarjan(0,-1); if(atype==1){printf("impossible\n");continue;} memset(head2,0,sizeof(head2)); s_edge2=0; for(i=0;i<n;i++) { for(int e=head[i];e;e=edge[e].nxt) { int v=edge[e].v; if(belon[i]!=belon[v]) addedge2(belon[i],belon[v]); } } ans=inf; dfs(1,0); printf("%d\n",ans); } return 0; }