• [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
  • 相关阅读:
    [蓝桥杯][基础训练]报时助手
    [蓝桥杯][基础训练]分解质因数
    [蓝桥杯][基础训练]2n皇后问题
    [啊哈算法]我要做月老
    [啊哈算法]关键道路(图的割边)
    [啊哈算法]重要城市(图的割点)
    并查集
    栈数组与栈链表代码实现

    循环链表
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11250628.html
Copyright © 2020-2023  润新知