hdu 2242 考研路茫茫——空调教室
2014-10-10 20:18
351 查看
题意:给一个双联通图(有重边),每一个节点有权值,现在要求把以一条边去掉,使得这个图分为两个部分,而且要使得这两个部分的权的差的绝对值最小;
思路:1,边_双连通求缩点,得到一颗树
2,简单树形dp
这题难倒我好久,首先是各种hash使得MLE,然后就是数组开小了,没有注意m的值有2W
最重大错误就在于建图了,一开始是在dfs函数里建图,但是这是错了,因为要low[site] == dfn[site] 我才建图,没有就会使得map保存的东西丢失,导致最终的树的边会少很多。
所以,建图要在dfs完了才建!!!!!
说到建图,这题是我第一个用邻接表建的图
代码如下:
思路:1,边_双连通求缩点,得到一颗树
2,简单树形dp
这题难倒我好久,首先是各种hash使得MLE,然后就是数组开小了,没有注意m的值有2W
最重大错误就在于建图了,一开始是在dfs函数里建图,但是这是错了,因为要low[site] == dfn[site] 我才建图,没有就会使得map保存的东西丢失,导致最终的树的边会少很多。
所以,建图要在dfs完了才建!!!!!
说到建图,这题是我第一个用邻接表建的图
struct Edge{ int end ; int next ; }; int head ; Edge err ; idx = 0 ; void add_edge(int a ,int b) { err[idx].end = b ; err[idx].next = head[a] ; head[a] = idx++ ; }首先,head的下标表示起点,end表示终点,next表示这条边的上一条边,next== -1表示结束
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <map> using namespace std ; const int Int = 30000+111 ; struct Graph { struct Edge{ int end ; int next ; }; Edge err[Int] ; int v ; vector<int> stk ; int head[Int] ; int instack[Int] ; int low[Int] , dfn[Int] ; int point[Int] ; int power[Int] ; int visit_time , color , minp , allp , idx ; int m ; multimap<int , int> mmap ; void init() { stk.clear() , mmap.clear() ; visit_time = 0 , color = 2 , minp= (1<<30) , idx = 0 , allp = 0 ; memset(instack , 0 , sizeof(instack)) ; memset(head , -1 , sizeof(head)) ; } void dfs(int site , int fa) { dfn[site] = low[site] = ++visit_time ; instack[site] = 1 ; stk.push_back(site) ; bool flag(false) ; int p = head[site] ; while(p != -1) { int f = err[p].end ; if(instack[f] == 0) { dfs(f , site) ; low[site] = min(low[site] , low[f]) ; } else if(instack[f] == 1) { if(f != fa) low[site] = min(low[site] , dfn[f]) ; else { if(flag) low[site] = min(low[site] , dfn[f]) ; else flag = true ; } } if(instack[f] > 1) { mmap.insert(make_pair(site , instack[f])) ; } p = err[p].next ; } if(low[site] == dfn[site]) { int f ,sum = 0 ; while(stk.back() != site) { f = stk.back() ; stk.pop_back() ; instack[f] = color ; sum += point[f] ; } stk.pop_back() ; sum += point[site] ; power[color] = sum ; instack[site] = color++ ; } } void add_edge(int a, int b) { err[idx].end = b ; err[idx].next = head[a] ; head[a] = idx++ ; } void build_trie() { idx = 0 ; memset(head , -1 , sizeof(head)) ; multimap<int ,int>::iterator it ; for(it = mmap.begin() ; it != mmap.end() ; ++it) { int f = instack[it->first] ; add_edge(f , it->second) ; add_edge(it->second , f) ; } } void search(int site , int fa , int& right) { int now = power[site] ; int p = head[site] ; while(p != -1){ int f = err[p].end ; if(f != fa) { search(f , site , now) ; } p = err[p].next ; } right += now ; int tmp = allp - 2*now ; if(tmp < 0) tmp = -tmp ; if(minp > tmp) minp = tmp ; } void std_fun() { init() ; for(int i= 1; i<= v ; ++i) { scanf("%d",point+i) ; allp += point[i] ; } int a, b; while(m--) { scanf("%d%d",&a ,&b) ; ++a , ++ b; add_edge(a , b) ; add_edge(b , a) ; } dfs(1 , 0) ; if(color == 3){ printf("impossible\n") ; return ; } build_trie() ; int tmp = power[2] ; search(2 , 0 , tmp ) ; printf("%d\n",minp) ; } }; Graph g ; int main() { while(scanf("%d%d",&g.v ,&g.m) == 2) { g.std_fun() ; } }
相关文章推荐
- HDU 2242 考研路茫茫——空调教室(边双连通)
- HDU 2242 考研路茫茫----空调教室
- HDU 2242 考研路茫茫——空调教室
- hdu 2242 考研路茫茫——空调教室
- hdu 2242 考研路茫茫——空调教室 点强连通+树形dp
- HDU 2242 考研路茫茫——空调教室
- HDU2242 考研路茫茫——空调教室 割边 缩点
- HDU 2242 考研路茫茫——空调教室(边双连通)
- HDU 2242 考研路茫茫 空调教室(tarjan bcc + tree dp)
- HDU 2242 考研路茫茫——空调教室【双连通分量+dp】
- HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)
- HDU 2242 考研路茫茫——空调教室
- 【HDU】2242 考研路茫茫——空调教室 双连通分量+树型DP
- hdu 2242 考研路茫茫——空调教室
- HDU 2242 双连通分量 考研路茫茫——空调教室
- HDU 2242 考研路茫茫——空调教室 (双连通分量+树形DP)
- hdu2242 考研路茫茫——空调教室 (双连通)
- hdu 2242 考研路茫茫——空调教室
- hdu 2242 考研路茫茫――空调教室 (双连通入门题)
- hdu 2242 考研路茫茫――空调教室(Tarjan+树型DP)