http://acm.hdu.edu.cn/showproblem.php?pid=6582
2019 多校第一场
跑两次dijstra确定最短路 然后把最短路上的边全部加入网络流 跑最小割
#include<bits/stdc++.h> #define maxn 10005 using namespace std; #define ll long long const ll INF = 0x3f3f3f3f3f3f3f3f; int head2[maxn],To2[maxn*20],Next2[maxn*20],vis[maxn]; int head[maxn],To[maxn*20],Next[maxn*20]; int dep[maxn],cur[maxn]; int cnt,S,T; int u[maxn],v[maxn]; ll w[maxn]; ll flow[maxn*20],cost2[maxn*20],dis1[maxn],dis2[maxn]; void add(int u,int v,ll w){ Next2[cnt]=head2[u]; head2[u]=cnt; To2[cnt]=v; cost2[cnt++]=w; } void add2(int u,int v,ll w){ Next[cnt]=head[u]; head[u]=cnt; To[cnt]=v; flow[cnt++]=w; } void init(int n){ for(int i=1;i<=n;i++){ head[i]=-1; head2[i]=-1; dis1[i]=INF; dis2[i]=INF; vis[i]=0; dep[i]=0; cur[i]=0; } cnt=0; } void dij(int s,ll dis[]){ priority_queue<pair<ll,int> , vector<pair<ll,int> > ,greater<pair<ll,int> > > q; q.push({0,s}); dis[s]=0; while(!q.empty()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; for(int i=head2[u];i!=-1;i=Next2[i]){ int v=To2[i]; if(dis[v]>dis[u]+cost2[i]){ dis[v]=dis[u]+cost2[i]; q.push({dis[v],v}); } } } } ll dfs(int u,ll cost){ if(u==T) return cost; for(int &i=cur[u];i!=-1;i=Next[i]){ if(dep[To[i]]==dep[u]+1&&flow[i]>0){ ll dis=dfs(To[i],min(flow[i],cost)); if(dis>0){ flow[i]-=dis; flow[i^1]+=dis; return dis; } } } return 0; } int bfs(){ queue<int> q; q.push(1); memset(dep,0,sizeof(dep)); dep[1]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=Next[i]){ if(flow[i]>0&&dep[To[i]]==0){ dep[To[i]]=dep[u]+1; q.push(To[i]); } } } if(dep[T]>0) return 1; return 0; } ll dicnic(){ ll ans=0; while(bfs()){ ll cost; for(int i=1;i<=T+2;i++){ cur[i]=head[i]; } while(cost=dfs(1,INF)) ans+=cost; } return ans; } int main(){ int t; scanf("%d",&t); while(t--){ int n,m; scanf("%d %d",&n,&m); init(n); for(int i=1;i<=m;i++){ scanf("%d %d %I64d",&u[i],&v[i],&w[i]); add(u[i],v[i],w[i]); } dij(1,dis1); for(int i=0;i<=n;i++){ vis[i]=0; head2[i]=-1; } cnt=0; for(int i=1;i<=m;i++){ add(v[i],u[i],w[i]); } dij(n,dis2); cnt=0; T=n; for(int i=1;i<=m;i++){ if(dis1[u[i]]+w[i]+dis2[v[i]]==dis1[n]){ add2(u[i],v[i],w[i]); add2(v[i],u[i],0); } } cout<<dicnic()<<" "; } return 0; }