[Loj]#6001. 「网络流 24 题」太空飞行计划

来源:互联网 发布:软件架构设计 autosar 编辑:程序博客网 时间:2024/06/06 01:46

分析后看出是最大权闭合子图,那么答案就是正权值-最大流。


#include <cstdio>#include <queue>#include <vector>#include <string>#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N=2505;const int inf=1<<29;int m,n,sum,s,t;int cur[155];int head[155];vector<int> in[155];struct edge{int nxt,v,ro,flow;}e[N];int tot=1;bool fl[155],fk[155];inline void add(int u,int v,int ro){e[++tot].v=v;e[tot].ro=ro;e[tot].nxt=head[u];head[u]=tot;e[++tot].v=u;e[tot].ro=0;e[tot].nxt=head[v];head[v]=tot;}int dis[155];bool vis[155];inline bool bfs(int s,int t){//memset(dis,-1,sizeof(dis));memset(vis,0,sizeof(vis));dis[s]=0;vis[s]=1;queue<int >q;q.push(s);while (!q.empty()){int x=q.front();q.pop();for (int i=head[x];i;i=e[i].nxt){if (!vis[e[i].v]&&e[i].ro>e[i].flow){q.push(e[i].v);dis[e[i].v]=dis[x]+1;vis[e[i].v]=1;}}}return vis[t];}int dfs(int x,int a){if (x==t||a==0) return a;int flow=0,f;for (int& i=cur[x];i;i=e[i].nxt){if (dis[x]+1==dis[e[i].v]&&((f=dfs(e[i].v,min(a,e[i].ro-e[i].flow)))>0)){flow+=f;e[i].flow+=f;e[i^1].flow-=f;a-=f;if (a==0) break;}}return flow;}inline int dinic(int s,int t){int i,flow=0;while (bfs(s,t)){for (i=0;i<=n+m+1;i++) cur[i]=head[i];flow+=dfs(s,inf);}return flow;}int main(){register int i,j;scanf("%d %d",&m,&n);char c=getchar ();c=getchar ();s=0,t=n+m+1;for (i=1;i<=m;i++){int w=0,x;string ch;getline(cin,ch);for (j=0;j<ch.size();j++){if (ch[j]<'0'||ch[j]>'9') continue;else  while (ch[j]>='0'&&ch[j]<='9'){w=w*10+ch[j]-'0';j++;}break;}sum+=w;add(s,i,w);for (j=j;j<ch.size();j++){if (ch[j]<'0'||ch[j]>'9'){x=0;continue;}else  while (ch[j]>='0'&&ch[j]<='9'){x=x*10+ch[j]-'0';j++;}in[i].push_back(x);add(i,m+x,inf);x=0;}}for (i=1;i<=n;i++){int x;scanf("%d",&x);add(m+i,t,x);}int maf=dinic(s,t);for (i=1;i<=m;i++){if (vis[i]) {printf("%d ",i);}}printf("\n");for (i=1;i<=n;i++)if (vis[i+m]) printf("%d ",i);printf("\n%d",sum-maf);return 0;}


原创粉丝点击