bzoj4057 状压dp不解释
数组不能开太大啊啊啊啊啊啊啊啊啊啊啊啊啊啊!
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstdlib> 7 #define rep(i,l,r) for(int i=l;i<r;i++) 8 #define down(i,r,l) for(int i=r;i>l;i--) 9 #define clr(a,x) memset(a,x,sizeof(a)) 10 #define b(a) (1<<(a)) 11 using namespace std; 12 const int maxn=20,maxs=b(20); 13 int d[maxn][maxn]; 14 bool dp[maxs]; 15 int main() 16 { 17 int t; 18 cin>>t; 19 while(t--){ 20 clr(dp,0); 21 clr(d,0); 22 int n; 23 bool flag=0; 24 scanf("%d",&n); 25 rep(i,0,n) 26 rep(j,0,n) 27 scanf("%d",&d[i][j]); 28 int all=b(n)-1; 29 dp[all]=1; 30 down(i,all,0){ 31 if(dp[i]){ 32 rep(j,0,n) 33 if(i&b(j)){ 34 int debt=0; 35 rep(k,0,n) 36 if(i&b(k)) debt+=d[k][j]; 37 if(debt<0) dp[i^b(j)]=1; 38 } 39 } 40 } 41 rep(i,0,n){ 42 if(dp[b(i)]){ 43 flag?printf(" "):flag=1; 44 printf("%d",i+1); 45 } 46 } 47 if(!flag) printf("0"); 48 printf("\n"); 49 } 50 return 0; 51 }
4057: [Cerc2012]Kingdoms
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 207 Solved: 99
[Submit][Status][Discuss]
Description
有一些王国陷入了一系列的经济危机。在很多年以前,他们私底下互相借了许多钱。现在,随着他们的负债被揭发,王国的崩溃不可避免地发生了……现在有n个王国,对于每对王国A和B,A欠B的钱被记为d_AB(我们假设有d_BA=-d_AB成立)。如果一个王国入不敷出(即需要支付超过所能获得的钱),它就可能破产。每当一个王国破产,与它相关的所有债务关系都会被去除,无论是正是负。而王国们的破产不是一瞬间完成的,而是第一个王国破产后,接下来可能破产的王国再继续破产,直到剩下的王国经济都是稳定的。不同的结局将取决于谁先破产,尤其是有的结局只会留下一个王国。请你计算,对于每个王国,是否存在一种结局使得该王国是唯一的幸存者。
Input
第一行一个正整数T,表示有T组数据。
每组数据第一行一个正整数n,表示有n个王国,1 <= n <= 20。
接下来n行,每行n个整数,第i行第j个整数表示d_ij,保证有d_ii = 0, d_ij = -d_ji, |d_ij| <= 10^6。
Output
每组数据输出一行,按照升序输出所有可能的王国编号,空格隔开,如果没有一个王国能满足条件,输出一个0。
Sample Input
1
3
0 -3 1
3 0 -2
-1 2 0
3
0 -3 1
3 0 -2
-1 2 0
Sample Output
1 3