代码如下:
/*This is the 16th problem of NF24
that Lucky_Yukikaze did
algo: minilized cut : max flow;
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<stdio.h>
#include<time.h>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<vector>
#include<utility>
#include<set>
#include<functional>
#include<climits>
using namespace std;
const int maxn=1300,maxm=120010;
const int inf=0x3f3f3f3f;
int n,m,s,t,ans,sum=0;
vector<int>pro,equ;
int vis[210];
struct edge{
int u,v,cap;
}e[maxm];
struct dinic{
int tp,s,t,dis[maxn],cur[maxn],que[maxn];
vector<edge>e;vector<int>v[maxn];
void AddEdge(int x,int y,int flw){
e.push_back(edge{x,y,flw});
e.push_back(edge{y,x,0});
v[x].push_back(e.size()-2);
v[y].push_back(e.size()-1);
}
int bfs(){
memset(dis,0x3f,sizeof(dis));
int l=1,r=1;que[1]=s;dis[s]=0;
while(l<=r){
int p=que[l++],to;
for(int i:v[p]){
if(e[i].cap&&dis[to=e[i].v]>1e9){
dis[to]=dis[p]+1;que[++r]=to;
}
}
}
return dis[t]<1e9;
}
int dfs(int p,int a){
if(p==t||!a)return a;
int sf=0,flw;
for(int &i=cur[p],to;i<(int)v[p].size();++i){
edge &E=e[v[p][i]];
if(dis[to=E.v]==dis[p]+1&&(flw=dfs(to,min(a,E.cap)))){
E.cap-=flw;e[v[p][i]^1].cap+=flw;
a-=flw;
sf+=flw;
if(!a)break;
}
}
return sf;
}
int Dinic(int s,int t,int tp=1){
this->s=s;this->t=t;this->tp=tp;
int flw=0;
while(bfs()){
memset(cur,0,sizeof(cur));
flw+=dfs(s,INT_MAX);
}
return flw;
}
void layout(){
bool flag=false;
for(int i=1;i<=n;i++){
if(dis[i]!=inf){
if(!flag){
flag=true;
}
else{
printf(" ");
}
printf("%d",i);
}
}
printf("\n");
flag=false;
for(int i=1;i<=m;i++){
if(dis[i+n]!=inf){
if(!flag){
flag=true;
}
else{
printf(" ");
}
printf("%d",i);
}
}
printf("\n");
}
}sol;
void in(int x){
char ch;
int tot=0;
while(1){
ch=getchar();
if(ch==' ')break;
tot=tot*10+(int)(ch-'0');
}
sum+=tot;
sol.AddEdge(s,x,tot);
while(ch!='\n'){
tot=0;
while(1){
ch=getchar();
if(ch==' '||ch=='\n')break;
tot=tot*10+(int)(ch-'0');
}
sol.AddEdge(x,n+tot,inf);
}
}
int main(){
scanf("%d %d",&n,&m);
//getchar();
getchar();
s=n+m+1;
t=n+m+2;
for(int i=1;i<=n;i++){
in(i);
}
int fl;
for(int i=1;i<=m;i++){
scanf("%d",&fl);
sol.AddEdge(n+i,t,fl);
}
ans=sol.Dinic(s,t,1);
pro.clear();equ.clear();
memset(vis,false,sizeof(vis));
sol.layout();
printf("%d",sum-ans);
return 0;
}
评测记录:链接(LOJ)
样例可以过,第一个点和样例一样,却过不了,真是鬼畜,本机运行也可以过。