[hdu6582]Path

首先,从1n跑一次dij,判断每一条边能否出现在最短路上,不能出现就删掉,然后将所有边建在图上,流量为边权,跑最小割即可。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 10005
  4 #define ll long long
  5 struct ji{
  6     int nex,to,len;
  7 }edge[N<<1];
  8 vector<ji>v;
  9 queue<int>q;
 10 int E,t,n,m,x,y,z,head[N],d[N],work[N];
 11 ll d1[N],d2[N];
 12 struct ji2{
 13     int k;
 14     bool operator < (const ji2 &a)const{
 15         return d1[k]>d1[a.k];
 16     }
 17 };
 18 priority_queue<ji2>qq;
 19 void add(int x,int y,int z){
 20     edge[E].nex=head[x];
 21     edge[E].to=y;
 22     edge[E].len=z;
 23     head[x]=E++;
 24 }
 25 void dij(int k){
 26     memset(d1,0x3f,sizeof(d1));
 27     qq.push(ji2{k});
 28     d1[k]=0;
 29     while (!qq.empty()){
 30         k=qq.top().k;
 31         qq.pop();
 32         for(int i=head[k];i!=-1;i=edge[i].nex){
 33             if (d1[k]+edge[i].len<d1[edge[i].to]){
 34                 d1[edge[i].to]=d1[k]+edge[i].len;
 35                 qq.push(ji2{edge[i].to});
 36             }
 37         }
 38     }
 39 }
 40 bool bfs(){
 41     memset(d,-1,sizeof(d));
 42     q.push(1);
 43     d[1]=0;
 44     while (!q.empty()){
 45         int k=q.front();
 46         q.pop();
 47         for(int i=head[k];i!=-1;i=edge[i].nex){
 48             int v=edge[i].to;
 49             if ((edge[i].len)&&(d[v]<0)){
 50                 d[v]=d[k]+1;
 51                 q.push(v);
 52             }
 53         }
 54     }
 55     return d[n]>=0;
 56 }
 57 int dfs(int k,int s){
 58     if (k==n)return s;
 59     int p;
 60     for(int i=work[k];i!=-1;i=edge[i].nex){
 61         int v=edge[i].to;
 62         if ((edge[i].len)&&(d[v]==d[k]+1)&&(p=dfs(v,min(s,edge[i].len)))){
 63             edge[i].len-=p;
 64             edge[i^1].len+=p;
 65             work[k]=i;
 66             return p;
 67         }
 68     }
 69     work[k]=-1;
 70     return 0;
 71 }
 72 ll dinic(){
 73     int k;
 74     ll ans=0;
 75     while (bfs()){
 76         memcpy(work,head,sizeof(head));
 77         while (k=dfs(1,0x3f3f3f3f))ans+=k;
 78     }
 79     return ans;
 80 }
 81 int main(){
 82     scanf("%d",&t);
 83     while (t--){
 84         scanf("%d%d",&n,&m);
 85         if (n==1){
 86             printf("0\n");
 87             continue;
 88         }
 89         E=0;
 90         memset(head,-1,sizeof(head));
 91         v.clear();
 92         for(int i=1;i<=m;i++){
 93             scanf("%d%d%d",&x,&y,&z);
 94             add(x,y,z);
 95             v.push_back(ji{x,y,z});
 96         }
 97         dij(1);
 98         memcpy(d2,d1,sizeof(d1));
 99         E=0;
100         memset(head,-1,sizeof(head));
101         for(int i=0;i<v.size();i++)add(v[i].to,v[i].nex,v[i].len);
102         dij(n);
103         v.clear();
104         for(int i=1;i<=n;i++)
105             for(int j=head[i];j!=-1;j=edge[j].nex)
106                 if (d1[i]+d2[edge[j].to]+edge[j].len==d1[1])v.push_back(ji{edge[j].to,i,edge[j].len});
107         E=0;
108         memset(head,-1,sizeof(head));
109         for(int i=0;i<v.size();i++){
110             add(v[i].nex,v[i].to,v[i].len);
111             add(v[i].to,v[i].nex,0);
112         }
113         printf("%lld\n",dinic());
114     }
115 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11250628.html