建图 等下整理到网络流学习笔记里去
有上下界的网络流
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
struct Chain
{
int u,flow,cost;
Chain *next,*Pair;
}*Head[100001];
int S,T;
inline void Add(int u,int v,int flow,int cost)
{
Chain *tp=new Chain;
tp->next=Head[u];
tp->u=v,tp->flow=flow,tp->cost=cost;
Head[u]=tp;
tp=new Chain;
tp->next=Head[v];
tp->u=u,tp->flow=0,tp->cost=-cost;
Head[v]=tp;
Head[v]->Pair=Head[u];
Head[u]->Pair=Head[v];
}
Chain *Pre[100001];
int Dis[100001],flow[100001];
queue<int>Q;
bool V[100001];
int ans;
const
int INF=1<<29;
int Mf;
inline bool SPFA(int S,int T)
{
memset(Dis,-1,sizeof(Dis));
Dis[S]=0;
V[S]=true;
Q.push(S);
flow[S]=INF;
while(!Q.empty())
{
int u=Q.front();
for(Chain *tp=Head[u];tp;tp=tp->next)
if(tp->flow&&(Dis[tp->u]==-1||Dis[tp->u]>Dis[u]+tp->cost))
{
Dis[tp->u]=Dis[u]+tp->cost;
Pre[tp->u]=tp;
flow[tp->u]=min(tp->flow,flow[u]);
if(!V[tp->u])
Q.push(tp->u),V[tp->u]=true;
}
V[u]=false;
Q.pop();
}
if(Dis[T]==-1)return false;
ans+=Dis[T]*flow[T];
int f=flow[T];
Mf+=f;
int t=T;
while(t^S)
{
Pre[t]->flow-=f,Pre[t]->Pair->flow+=f;
t=Pre[t]->Pair->u;
}
return true;
}
int Du[10001];
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
int st,ed;
int main()
{
int i,j,k,t,n,L;
read(n);
S=n+1,T=n+2,st=1,ed=0;
for(i=1;i<=n;i++)
{
read(k);
Add(i,T,k,0);
if(i^1)Add(i,1,INF,0);
for(j=1;j<=k;j++)
{
read(t),read(L);
Add(S,t,1,L);
Add(i,t,INF,L);
}
}
while(SPFA(S,T));
printf("%d\n",ans);
return 0;
}