HDOJ树形DP专题之考研路茫茫——空调教室
2012-05-02 14:59
344 查看
题目链接
题目大意:给定一个连通无向图,每个结点有一个值,现要断开图中某条边,使得原图变成两个连通子图,且要使两个子图的值的差最小。输出最小差,若无法完成,则输出"impossible”
分析:要使断开某条边后,原图变成两个连通支,则断开的边一定是桥。对图进行DFS时,得到一颗树,图中有的而树中没有的边叫回边,回边一定不是桥。由此想到可用dfs将图转化为树来做,但树中的边不一定是原图中的桥,问题关键在于桥的判断。此题还需要注意的是可能有重边。
View Code
题目大意:给定一个连通无向图,每个结点有一个值,现要断开图中某条边,使得原图变成两个连通子图,且要使两个子图的值的差最小。输出最小差,若无法完成,则输出"impossible”
分析:要使断开某条边后,原图变成两个连通支,则断开的边一定是桥。对图进行DFS时,得到一颗树,图中有的而树中没有的边叫回边,回边一定不是桥。由此想到可用dfs将图转化为树来做,但树中的边不一定是原图中的桥,问题关键在于桥的判断。此题还需要注意的是可能有重边。
View Code
#include <stdio.h> #include <math.h> #include <string.h> #include <vector> #define N 10001 #define M 40001 #define INF 0x7fffffff #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) using namespace std; vector<int> dep ; int u[M],v[M],cnt[M],next[M],first ,n,m; int num ,sum ; int p ,d ,dfn ,low ,dmax,id; char vis ; void dfs(int a,int fa) { int e,b; d[a]=(fa==-1?0:d[fa]+1); dmax=MAX(dmax,d[a]); dep[d[a]].push_back(a); for(e=first[a];e>=0;e=next[e]) { b=v[e]; if(b==fa) continue; if(vis[b]) low[a]=MIN(low[a],dfn[b]); else { vis[b]=1; dfn[b]=low[b]=++id; dfs(b,p[b]=a); low[a]=MIN(low[a],low[b]); } } } void dp() { int e,b,i,j; memset(sum,0,sizeof(sum)); for(i=dmax;i>=0;i--) { for(j=0;j<dep[i].size();j++) { b=dep[i][j]; sum[b]+=num[b]; if(i) sum[p[b]]+=sum[b]; } } } void addEdge(int a,int b,int e) { u[e]=a,v[e]=b; cnt[e]=1; next[e]=first[a]; first[a]=e; } int findEdge(int a,int b) { int e; for(e=first[a];e>=0;e=next[e]) { if(v[e]==b) { cnt[e]++; return 1; } } return 0; } int main() { int i,e,a,b,ans; while(~scanf("%d%d",&n,&m)) { for(i=0;i<n;i++) scanf("%d",&num[i]); memset(u,-1,sizeof(u)); memset(v,-1,sizeof(v)); memset(first,-1,sizeof(first)); memset(next,-1,sizeof(next)); memset(cnt,0,sizeof(cnt)); for(e=0;e<m;e++) { scanf("%d%d",&a,&b); if(findEdge(a,b)+findEdge(b,a)==0) { addEdge(a,b,2*e); addEdge(b,a,2*e+1); } } memset(vis,0,sizeof(vis)); vis[0]=1; dfn[0]=low[0]=id=1; p[0]=-1; dmax=0; for(i=0;i<n;i++) dep[i].clear(); dfs(0,-1); dp(); ans=INF; for(e=0;e<m;e++) { if(cnt[2*e]>1) continue; a=u[2*e],b=v[2*e]; if(p[a]==b&&low[a]>dfn[b]) ans=MIN(ans,abs(2*sum[a]-sum[0])); else if(p[b]==a&&low[b]>dfn[a]) ans=MIN(ans,abs(2*sum[b]-sum[0])); } if(ans==INF) puts("impossible"); else printf("%d\n",ans); } return 0; }
相关文章推荐
- hdoj 2242 考研路茫茫——空调教室 【无向图求边双联通 缩点 + 树形dp】
- HDU2242 考研路茫茫——空调教室(tarjan+树形DP)
- hdu 2242 考研路茫茫——空调教室 点强连通+树形dp
- 【双连通分量(tarjan)+树形dp】HDU-2242-考研路茫茫——空调教室
- HDU 2242 考研路茫茫——空调教室 (双连通分量+树形DP)
- HDU - 2242M - 考研路茫茫——空调教室【双联通分量+树形DP】
- HDU_2242 考研路茫茫——空调教室 tarjin+树形dp
- HDU 2242 考研路茫茫——空调教室 无向图缩环+树形DP
- HDOJ 2242 考研路茫茫——空调教室
- HDU2242 考研路茫茫——空调教室 (割桥 + dp)
- 【双连通分量】 HDOJ 2242 考研路茫茫——空调教室
- HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)
- hdu 2242 考研路茫茫——空调教室 【Tarjan缩点+树上DP】 解题报告
- HDU2242 考研路茫茫——空调教室 解题报告【边双联通分量+树上dp】
- HDU 2242 考研路茫茫 空调教室(tarjan bcc + tree dp)
- 【HDOJ】2242 考研路茫茫——空调教室
- HDU - 2242 考研路茫茫――空调教室(树形DP+强连通分量)
- HDOJ 2242 考研路茫茫——空调教室
- HDOJ树形DP专题之Tree Cutting
- hdu2242考研路茫茫——空调教室