ZOJ1609-Equivalence

来源:互联网 发布:太空望远镜软件 编辑:程序博客网 时间:2024/06/15 03:56

Equivalence

Time Limit: 5 Seconds      Memory Limit: 32768 KB

When learning mathamatics, sometimes one may come to an theorem which goes like this:

The following statements are equivalent:

a)......
b)......
c)......

For example, let A be an angle between 0 and 360 degrees, the following statements are equivalent:

a)A = 90 degrees;
b)A is a right angle;
c)sin(A) = 1.

Proving such a theorem is usually a difficult task, because you have to prove that for any two statements Si and Sj, Si concludes Sj and vise versa. Sometimes, proving Si concludes Sj directly is quite difficult so we may find a Sk and prove that Si concludes Sk and Sk concludes Sj. Now given the difficulty of proving every Si => Sj, you are to calculate the minimal total difficulty to prove that the given statements are equivalent.


Input

The input contains several cases. Each case begins with an integer n (2 <= n <= 6), the number of statements in this case, followed by n lines, each contains n integers.

The jth integer of the ith row represents the difficulty of proving Si => Sj. The ith integer of the ith row is always 0 as it's obvious that Si concludes Si. All the n * n integers are between 0 and 100, inclusively. Input is terminated by EOF.


Output

For each test case, output a line with the minimal difficulty for that case.


Sample Input

4
0 2 3 4
5 0 7 8
9 10 0 12
13 14 15 0


Sample Output

34



Author: PAN, Minghao
Source: ZOJ Monthly, May 2003


题意:有n个点,告诉你两两之间有向边的权值,问使整张图强连通的最小权值为多少

解题思路:暴搜+剪纸+状态压缩


#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <queue>#include <vector>#include <bitset>using namespace std;#define LL long longconst int INF = 0x3f3f3f3f;const double pi = acos(-1.0);struct node{int x, y, sum;} xx[50];int n, cnt, mi,m;int a[10][10], b[50][8];bool cmp(node xx, node yy){return xx.sum < yy.sum;}void dfs(int x,int sum){if (sum >= mi) return;int res = 0;for (int i =0 ; i < n; i++){res += b[x][i] == m;b[x + 1][i] = b[x][i];}if (res==n){mi = min(mi, sum);return;}if(x==cnt) return ;for (int i = 0; i < n; i++){b[x + 1][i] = b[x][i];if (b[x][i] & (1 << xx[x].x)){b[x + 1][i] |= b[x][xx[x].y];}}dfs(x + 1, sum + xx[x].sum);for (int i = 0; i < n; i++) b[x + 1][i] = b[x][i];dfs(x + 1, sum);}int main(){while (~scanf("%d", &n)){cnt = 0;m = (1 << n) - 1;for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){scanf("%d", &a[i][j]);if (i == j) continue;xx[cnt].x = i, xx[cnt].y = j, xx[cnt++].sum = a[i][j];}}sort(xx,xx+cnt,cmp);for (int i = 0; i < n; i++)  b[0][i] = 1 << i;mi = INF;dfs(0, 0);printf("%d\n", mi);}return 0;}

0 0
原创粉丝点击