时间限制:500MS 内存限制:65536K
提交次数:24 通过次数:18
题型: 编程题 语言: G++;GCC
Description
如下图所示,有若干珠子,每颗珠子重量不同,珠子之间有一些细线将它们连在一起。现要求切断一些细线,将它们分成两部分,分割后,单独每一部分的珠子仍保持相连,且要求尽量做到两部分总重相等或相差最少。 请编一程序,给定珠子个数、每颗珠子的重量以及珠子之间的连接情况,输出按上述要求分割后两部分总重的差值的绝对值。
输入格式
第一行有两个数N与M(1<=N,M<=10),N为珠子个数(珠子编号依次为1,2,3,...,N),M为连接珠子的细线数目。第二行为N个正整数,分别为N个珠子的重量。此后M行,每行两个数X与Y,表示珠子X与珠子Y由细线相连。
输出格式
按要求分割后两部分总重的差值的绝对值。
输入样例
5 5 1 2 3 4 1 1 2 1 3 2 3 3 4 4 5
输出样例
1
题意:给出一个图,将图分成两半,每一部分都需要保持连通,问分开能得到的最小差值
思路:n最大只有10,可以枚举n的所有组合作为其中一半,然后判断这一半所有节点是否连通,然后再判断剩下的所有节点是否连通,从所有组合中得到最小差值
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 #include <queue> 7 #include <vector> 8 using namespace std ; 9 int a[12], G[12][12], vis[12] ; 10 int n, m, sx ; 11 vector<int> vc;//vc里面存储当前枚举到的节点,并判断连通性 12 void dfs(int cur)//dfs标记 13 { 14 vis[cur] = 1 ; 15 for(int i = 1; i <= n; ++i) 16 if(!vis[i] && G[cur][i]) dfs(i) ; 17 } 18 int _union()//判断连通性 19 { 20 int leap = 0 ; 21 for(int i = 0; i < sx; ++i){ 22 leap = 0 ; 23 for(int j = 0; j < sx; ++j) if(i != j){ 24 if(G[ vc[i] ][ vc[j] ]){ 25 leap = 1; 26 break ; 27 } 28 } 29 if(!leap) break ; 30 } 31 if(!leap) return 0 ; 32 else return 1 ; 33 } 34 int check() 35 { 36 sx = vc.size() ; 37 if(vc.size() > 2) if(!_union()) return 0 ; 38 for(int k = 1; k <= n; ++k) if(!vis[k]){ 39 dfs(k) ; 40 break ; 41 } 42 for(int i = 1; i <= n; ++i) 43 if(!vis[i]) return 0 ; 44 return 1 ; 45 } 46 int main() 47 { 48 int u, v, sum = 0, mi = 1 << 25, flag ; 49 memset(G, 0, sizeof G) ; 50 scanf("%d%d",&n,&m) ; 51 for(int i = 1; i <= n; ++i){ 52 scanf("%d",&a[i]) ; 53 sum += a[i] ; 54 } 55 flag = sum >> 1 ;//以sum的一半作为flag 56 for(int i = 1; i <= m ; ++i){ 57 scanf("%d%d",&u,&v) ; 58 G[u][v] = 1 ; 59 G[v][u] = 1 ; 60 } 61 for(int i = 1; i < (1 << n); ++i)//枚举所有的组合 62 { 63 int now = 0 ; 64 vc.clear() ; 65 memset(vis, 0, sizeof vis) ; 66 for(int j = 1; j <= n; ++j) 67 if(i & (1 << (j - 1))){ 68 vis[j] = 1 ; 69 now += a[j] ; 70 vc.push_back(j) ; 71 } 72 if(now < flag || now >= mi) continue ; 73 if(check()) mi = now ; 74 } 75 printf("%d ",abs(sum - 2 * mi)) ; 76 }
修改一下,当vc.size() == 2 时, 也要判断这两个节点的连通性