http://acm.hdu.edu.cn/showproblem.php?pid=5889
题意:敌人在n点,敌人会走n到1的最短路径进攻你了,现在你需要在路径上放置障碍,求能阻挡所有敌人放置最少价值的障碍。
思路:我们先对原图跑最短路,然后重新建图跑dicnic 注意使用弧优化
#include<bits/stdc++.h> #define maxn 1005 using namespace std; #define ll long long const int INF = 0x3f3f3f3f; int head2[1005],To2[maxn*20],Next2[maxn*20],dis[maxn],cost2[maxn*20],vis[maxn]; int head[1005],To[maxn*20],Next[maxn*20]; int flow[maxn*20],dep[maxn],cur[maxn]; int cnt,S,T; void add(int u,int v,int w){ Next2[cnt]=head2[u]; head2[u]=cnt; To2[cnt]=v; cost2[cnt++]=w; } void add2(int u,int v,int w){ Next[cnt]=head[u]; head[u]=cnt; To[cnt]=v; flow[cnt++]=w; } void init(){ memset(head,-1,sizeof(head)); memset(head2,-1,sizeof(head2)); memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(dep,0,sizeof(dep)); memset(cur,0,sizeof(cur)); cnt=0; } void dij(){ priority_queue<pair<int,int> , vector<pair<int,int> > ,greater<pair<int,int> > > q; q.push({0,1}); dis[1]=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]+1){ dis[v]=dis[u]+1; q.push({dis[v],v}); } } } } int dfs(int u,int 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){ int 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; } int dicnic(){ int ans=0; while(bfs()){ int 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--){ init(); int n,m; scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d %d %d",&u,&v,&w); add(u,v,w); add(v,u,w); } dij(); // cout<<dis[n]<<endl; cnt=0; T=n; for(int i=1;i<=n;i++){ for(int j=head2[i];j!=-1;j=Next2[j]){ // cout>> if(dis[i]+1==dis[To2[j]]){ add2(i,To2[j],cost2[j]); add2(To2[j],i,0); // cout<<i<<" "<<To[j]<<endl; } } } cout<<dicnic()<<"\n"; } return 0; }