---恢复内容开始---
大脑有点晕。先做点水题练练手吧。(主要是在下网络流太菜,准备复习下)
每个剧情都要看,那就是每条边都要走一次嘛。不说了,费用流模板,把所有边的流量下限置为1,直接跑就行了。
默认无源汇上下界的大家都会做。
那么,从汇点向源点连一条费用为0,流量无限的边就满足所有点都流量守恒了,转为无源汇上下界模型。
代码不长。(然而我写得丑还是要承认的。)
#include<bits/stdc++.h> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<deque> #include<list> #include<set> #include<vector> #include<iostream> #define ll long long #define re register #define inf 0x3f3f3f3f #define inl inline #define sqr(x) (x*x) //#define eps 1e-8 #define debug printf("debug "); //#pragma comment(linker, "/STACK:1024000000,1024000000") //#pragma GCC optimize (2) //#pragma G++ optimize (2) using namespace std; const ll mod=51123987; const ll MAXN=505; inl ll read() { re ll x = 0; re int f = 1; char ch = getchar(); while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); } while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x * f; } inl char readc() { char ch=getchar(); while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar(); return ch; } inl void write(re ll x){ if(x>=10)write(x/10); putchar(x%10+'0'); } inl void writeln(re ll x){ if(x<0) {x=-x;putchar('-');} write(x); puts(""); } inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;} inl ll Lcm(re ll a,re ll b) {return a/gcd(a,b)*b;} inl void FR() { freopen(".in","r",stdin); freopen(".out","w",stdout); } inl void FC() { fclose(stdin); fclose(stdout); } ll head[MAXN],cnt; struct edge { ll u,v,w,nxt,val,pd; }e[(MAXN*MAXN)<<1]; inl void adde(ll u,ll v,ll w,ll val) { e[++cnt].u=u;e[cnt].v=v;e[cnt].w=w; e[cnt].val=val;e[cnt].nxt=head[u];head[u]=cnt; } ll ans,n,dis[MAXN],cur[MAXN]; ll sum[MAXN],pre[MAXN],flow[MAXN]; bool in[MAXN]; bool spfa() { memset(dis,inf,sizeof(dis)); deque<ll>Q; while(!Q.empty()) Q.pop_back(); Q.push_back(0);in[0]=1;dis[0]=0;flow[0]=inf; while(!Q.empty()) { ll x=Q.front();Q.pop_front();in[x]=0; for(re ll h=head[x];h;h=e[h].nxt) { if(e[h].w<=0) continue ; re ll v=e[h].v; if(dis[v]<=dis[x]+e[h].val) continue ; dis[v]=dis[x]+e[h].val; pre[v]=h;flow[v]=min(flow[x],e[h].w); if(in[v]) continue ; if(Q.empty()||dis[v]<dis[Q.front()]) {Q.push_front(v);in[v]=1;} else {Q.push_back(v);in[v]=1; } } } return dis[n+2]-dis[n+3]; } ll dinic() { ll sum=0; while(spfa()) { ll x=n+2; while(x!=0) { ll h=pre[x];e[h].w-=flow[n+2]; e[e[h].pd].w+=flow[n+2];x=e[h].u; } ans+=flow[n+2]*dis[n+2]; } return sum; } int main() { // FR(); n=read();ans=0; for(re ll i=1;i<=n;i++) { re ll x=read(); for(re ll j=1;j<=x;j++) { re ll v=read(),val=read(); ans+=val;sum[i]--;sum[v]++; adde(i,v,inf,val);e[cnt].pd=cnt+1; adde(v,i,0,-val);e[cnt].pd=cnt-1; } } for(re ll i=2;i<=n;i++) { adde(i,n+1,inf,0);e[cnt].pd=cnt+1; adde(n+1,i,0,0);e[cnt].pd=cnt-1; } for(re ll i=1;i<=n;i++) { if(sum[i]>0) { adde(0,i,sum[i],0);e[cnt].pd=cnt+1; adde(i,0,0,0);e[cnt].pd=cnt-1; } if(sum[i]<0) { adde(i,n+2,-sum[i],0);e[cnt].pd=cnt+1; adde(n+2,i,0,0);e[cnt].pd=cnt-1; } } adde(n+1,1,inf,0);e[cnt].pd=cnt+1;//加上从汇点到原点的,费用为0,就满足所有点流量平衡,当做无源汇来做了 adde(n+1,1,inf,0);e[cnt].pd=cnt-1; dinic(); writeln(ans); // FC(); return 0; }