感觉自己弱得没救了。。。求神犇解救T_T
1
2597: [Wc2007]剪刀石头布
补集转化之后就是费用流了。我比较逗方案WA了两发。
1 int n,m,k,mincost,tot=1,cnt,s,t,win[maxn],a[maxn][maxn],b[maxn][maxn],head[maxm],d[maxm],from[2*maxm]; 2 3 bool v[maxm]; 4 5 queue<int>q; 6 7 struct edge{int from,go,next,v,c;}e[2*maxm]; 8 9 void add(int x,int y,int v,int c) 10 11 { 12 13 e[++tot]=(edge){x,y,head[x],v,c};head[x]=tot; 14 15 e[++tot]=(edge){y,x,head[y],0,-c};head[y]=tot; 16 17 } 18 19 bool spfa() 20 21 { 22 23 for (int i=0;i<=cnt;i++){v[i]=0;d[i]=inf;} 24 25 q.push(s);d[s]=0;v[s]=1; 26 27 while(!q.empty()) 28 29 { 30 31 int x=q.front();q.pop();v[x]=0; 32 33 for (int i=head[x],y;i;i=e[i].next) 34 35 if(e[i].v&&d[x]+e[i].c<d[y=e[i].go]) 36 37 { 38 39 d[y]=d[x]+e[i].c;from[y]=i; 40 41 if(!v[y]){v[y]=1;q.push(y);} 42 43 } 44 45 } 46 47 return d[t]!=inf; 48 49 } 50 51 void mcf() 52 53 { 54 55 while(spfa()) 56 57 { 58 59 int tmp=inf; 60 61 for(int i=from[t];i;i=from[e[i].from]) tmp=min(tmp,e[i].v); 62 63 mincost+=d[t]*tmp; 64 65 for(int i=from[t];i;i=from[e[i].from]){e[i].v-=tmp;e[i^1].v+=tmp;} 66 67 } 68 69 } 70 71 int main() 72 73 { 74 n=read();s=0;t=n+1;cnt=t; 75 for5(n,n)a[i][j]=read(),win[i]+=(a[i][j]==1); 76 for1(i,n)for1(j,i-1)if(a[i][j]==2) 77 { 78 add(s,++cnt,1,0); 79 b[i][j]=tot+1; 80 add(cnt,i,1,0); 81 add(cnt,j,1,0); 82 } 83 for1(i,n) 84 { 85 mincost+=win[i]*(win[i]-1)/2; 86 for2(j,win[i],n-2)add(i,t,1,j); 87 } 88 mcf(); 89 cout<<(n*(n-1)*(n-2)/6-mincost)<<endl; 90 for1(i,n)for1(j,i-1)if(a[i][j]==2)a[i][j]=!e[b[i][j]].v,a[j][i]=!a[i][j]; 91 for1(i,n)for1(j,n)printf("%d%c",a[i][j],j==n?‘\n‘:‘ ‘); 92 93 return 0; 94 95 }
时间: 2024-10-11 12:43:21