传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2597
wc的题不看题解能做? http://xietutu.com/archives/958
话说lrj的费用流模板常数真是一坨翔,好在氧气+linux+神评测机让我卡时过了
Code:
#include<bits/stdc++.h> using namespace std; const int maxn=20010; struct edge{int u,v,cap,flow,cost;}; vector<edge>edges; vector<int>G[maxn]; void add(int u,int v,int cap,int cost){ edges.push_back((edge){u,v,cap,0,cost}); G[u].push_back(edges.size()-1); edges.push_back((edge){v,u,0,0,-cost}); G[v].push_back(edges.size()-1); } int flow=0,cost=0,s,t,n; int a[maxn],pre[maxn],d[maxn],in[maxn]; typedef pair<int,int> par; #define fst first #define sec second par mp[maxn]; bool spfa(){ static int vis[maxn]; queue<int>q; memset(d,0x3f,sizeof d);int B=d[0]; q.push(s);d[s]=0;a[s]=INT_MAX; while(!q.empty()){ int u=q.front();q.pop();vis[u]=0; for(int i=0;i<G[u].size();i++){ edge e=edges[G[u][i]]; if(e.cap>e.flow&&d[e.v]>d[u]+e.cost){ d[e.v]=d[u]+e.cost; pre[e.v]=G[u][i]; a[e.v]=min(a[u],e.cap-e.flow); if(!vis[e.v]){ vis[e.v]=1; q.push(e.v); } } } }if(d[t]==B)return false; flow+=a[t];cost+=d[t]*a[t]; int u=t; while(u!=s){ edges[pre[u]].flow+=a[t]; edges[pre[u]^1].flow-=a[t]; u=edges[pre[u]].u; }return true; } int main(){ scanf("%d",&n);int m=n*(n-1)/2,cnt=0; s=0;t=n+m+1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ int x; scanf("%d",&x); if(j<=i)continue; cnt++;mp[cnt]=par(i,j); if(x==2)add(cnt,i+m,1,0),add(cnt,j+m,1,0),in[i]++,in[j]++; if(x==1)add(cnt,i+m,1,0),in[i]++; if(x==0)add(cnt,j+m,1,0),in[j]++; }for(int i=1;i<=m;i++)add(s,i,1,0); for(int i=1;i<=n;i++) for(int j=1;j<=in[i];j++) add(i+m,t,1,2*j-1); while(spfa()); cout<<(n*(n-1)*(n-2)/3+m-cost)/2<<endl; static int a[101][101],tot=0; for(int i=0;i<edges.size();i++)if(i%2==0){ int u=edges[i].u,v=edges[i].v-m; if(u>=1&&u<=m&&v>=1&&v<=n&&edges[i].flow==1){ a[mp[u].fst][mp[u].sec]=v==mp[u].fst; a[mp[u].sec][mp[u].fst]=v!=mp[u].fst; } } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) printf("%d%c",a[i][j]," \n"[j==n]); return 0; }