标签:des style blog http color os io strong ar
3 2
10 0
20 0
-10 0
-5 1 0 0
100 1 2 1
100 0
25
正如题解所说,这道题就是一个最大权闭合图,唯一一点要注意的是,由于连边较多,所以边表数组要尽量开大一些,否则RE#9,而且尽量舍去图中的重边,否则TLE#9.
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define MAXN 42 #define MAXM 63 #define MAXB MAXN*MAXM*4 #define MAXV MAXB*4 #define MAXE MAXB*1000 #define INF 0x3f3f3f3f vector<int> att[MAXB]; int score[MAXB]; struct Edge { int np,val; Edge *next,*neg; }E[MAXE],*V[MAXV]; int tope=-1; int sour=0,sink=1; void addedge(int x,int y,int z) { //cout<<"ADD:"<<x<<" "<<y<<" "<<z<<endl; E[++tope].np=y; E[tope].val=z; E[tope].next=V[x]; V[x]=&E[tope]; E[++tope].np=x; E[tope].val=0; E[tope].next=V[y]; V[y]=&E[tope]; E[tope].neg=&E[tope-1]; E[tope-1].neg=&E[tope]; } int lev[MAXV]; int dfs(int now,int maxf) { int ret=0,t; Edge *ne; if(now==sink)return maxf; for (ne=V[now];ne;ne=ne->next) { if (lev[ne->np]!=lev[now]+1 || !ne->val)continue; t=dfs(ne->np,min(maxf,ne->val)); ne->val-=t; ne->neg->val+=t; ret+=t; maxf-=t; } if (!ret) lev[now]=-1; return ret; } int q[MAXV]; int vis[MAXV],bfstime=0; bool bfs() { int head=-1,tail=0; int now; Edge *ne; q[0]=sour; vis[sour]=++bfstime; while (head<tail) { now=q[++head]; for (ne=V[now];ne;ne=ne->next) { if (!ne->val || vis[ne->np]==bfstime)continue; vis[ne->np]=bfstime; lev[ne->np]=lev[now]+1; q[++tail]=ne->np; } } return vis[sink]==bfstime; } int dinic() { int ret=0; while (bfs()) { ret+=dfs(sour,INF); } return ret; } int low[MAXB],dfn[MAXB]; int dfstime=0; int stack[MAXB],tops=-1; bool ok[MAXB]; void tarjan(int now) { int i,j; low[now]=dfn[now]=++dfstime; stack[++tops]=now; for (i=0;i<att[now].size();i++) { if (vis[att[now][i]])continue; if (!dfn[att[now][i]]) { tarjan(att[now][i]); low[now]=min(low[now],low[att[now][i]]); }else { low[now]=min(low[now],dfn[att[now][i]]); } } if (low[now]==dfn[now]) { if (stack[tops]==now) { tops--; }else { while (stack[tops]!=now) { ok[stack[tops--]]=false; } ok[stack[tops--]]=false; } } vis[now]=1; } int main() { freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); int i,j,k,x,y,z,n,m; scanf("%d%d",&n,&m); for (i=0;i<n;i++) { for (j=0;j<m;j++) { scanf("%d%d",&score[i*m+j],&x); for (k=0;k<x;k++) { scanf("%d%d",&y,&z); if (y==i && z<j)continue; att[i*m+j].push_back(y*m+z); } } } for (i=0;i<n;i++) { for (j=0;j<m;j++) { for (k=0;k<j;k++) { att[i*m+j].push_back(i*m+k); } } } int l=n*m; memset(vis,0,sizeof(vis)); memset(ok,1,sizeof(ok)); for (i=0;i<l;i++) { if (!dfn[i]) tarjan(i); } bool flag; for (i=0;i<l;i++) { for (j=0;j<att[i].size();j++) { if (!ok[att[i][j]])continue; addedge(2+att[i][j],2+i,INF); } } int ans=0; for (i=0;i<n;i++) { for (j=m-1;j>=0;j--) { if (!ok[i*m+j])break; if (score[i*m+j]>=0) { addedge(sour,2+i*m+j,score[i*m+j]); ans+=score[i*m+j]; }else { addedge(2+i*m+j,sink,-score[i*m+j]); } } } ans-=dinic(); printf("%d\n",ans); return 0; }
标签:des style blog http color os io strong ar
原文地址:http://www.cnblogs.com/mhy12345/p/3951241.html