PS:zkw跑的飞快,不过rank前两页怎么会那么快......不是一个复杂度级的啊....
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘)f=-1; ch=getchar();}
while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();}
return x*f;
}
#define maxn 310
#define maxm 1000100
int n;
struct EdgeNode{int next,to,cap,cost;}edge[maxm];
int head[maxn],cnt=1;
void add(int u,int v,int w,int c)
{
cnt++;
edge[cnt].cap=w;edge[cnt].cost=c;edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt;
}
void insert(int u,int v,int w,int c) {add(u,v,w,c); add(v,u,0,-c);}
int dis[maxn],S,T,MinCost; bool mark[maxn];
#define inf 0x7fffffff
bool spfa()
{
queue<int>q; memset(mark,0,sizeof(mark));
for (int i=S; i<=T; i++) dis[i]=inf;
q.push(T); dis[T]=0; mark[T]=1;
while (!q.empty())
{
int now=q.front(); q.pop(); mark[now]=0;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i^1].cap && dis[edge[i].to]>dis[now]+edge[i^1].cost)
{
dis[edge[i].to]=dis[now]+edge[i^1].cost;
if (!mark[edge[i].to])
q.push(edge[i].to),mark[edge[i].to]=1;
}
}
return dis[S]!=inf;
}
int dfs(int loc,int low)
{
mark[loc]=1;
if (loc==T) return low;
int w,used=0;
for (int i=head[loc]; i; i=edge[i].next)
if (edge[i].cap && !mark[edge[i].to] && dis[edge[i].to]==dis[loc]-edge[i].cost)
{
w=dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^1].cap+=w; used+=w; MinCost+=w*edge[i].cost;
if (used==low) return low;
}
return used;
}
int zkw()
{
int tmp=0;
while (spfa())
{
mark[T]=1;
while (mark[T])
memset(mark,0,sizeof(mark)),tmp+=dfs(S,inf);
}
return tmp;
}
int main()
{
n=read(); S=0,T=n+1;
for (int i=1; i<=n; i++)
{
int m=read();
for (int v,c,j=1; j<=m; j++)
v=read(),c=read(),insert(i,v,inf,c),insert(S,v,1,c);
insert(i,T,m,0);
if (i!=1) insert(i,1,inf,0);
}
zkw(); printf("%d\n",MinCost);
return 0;
}