zoukankan      html  css  js  c++  java
  • hdu 3416 Marriage Match IV 【 最短路 最大流 】

    求边不可重复的最短路条数

    先从起点到终点用一次dijkstra,再从终点到起点用一次dijkstra,来判断一条边是否在最短路上

    如果在,就将这条边的两个端点连起来,容量为1

    再跑一下dinic(),最大流就是不可重复的最短路条数

    还是想不到怎么建图啊------

    每次做网络流的题目---

    诶---该怎么建图啊---

    想了一会儿----啊--不会啊---

    搜一下题解吧---

    啊,原来这样连边啊---

    啊,原来需要---floyd / 并查集 /dijkstra /------

    啊---快,粘一粘模板---

    恩--试着跑一发---

    诶--怎么不对---

    原来数组开小了,,终点没有改过来--

    好,厚着脸皮交一发---

    哇----居然过了-------------------------------------------------

    可是还是不会写网络流

    唉--不说了---滚了---

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <vector>
      6 #include <map>
      7 #include <set>
      8 #include <stack>
      9 #include <queue>
     10 #include <iostream>
     11 #include <algorithm>
     12 #define MP(a,b) make_pair(a,b)
     13 using namespace std;
     14 
     15 typedef long long ll;
     16 typedef unsigned long long ull;
     17 typedef pair<int,int> pii;
     18 const int INF = (1 << 30) - 1;
     19 const int maxn = 100055;
     20 
     21 int path;
     22 int first1[maxn],nxt1[10 * maxn],ecnt1;
     23 int first2[maxn],nxt2[10 *maxn],ecnt2;
     24 int first[maxn],nxt[10*maxn],ecnt;
     25 int dis1[maxn],dis2[maxn];
     26 int st,ed,lev[maxn],now[maxn];
     27 int n,m;
     28 
     29 int vis[20*maxn];
     30 
     31 struct edge{
     32     int v,u,cost;
     33     int c;
     34     int next;
     35     friend bool operator < (edge a,edge b){
     36         return a.cost > b.cost;
     37     }
     38 };
     39 
     40 edge e1[5*maxn],e2[5*maxn],e[5*maxn];
     41 
     42 void init(){
     43     ecnt1 = ecnt2 = ecnt = 0;
     44     memset(first1,-1,sizeof(first1));
     45     memset(first2,-1,sizeof(first2));
     46     memset(first,-1,sizeof(first));
     47 }
     48 
     49 void Add_edge1(int u,int v,int c){
     50     nxt1[++ecnt1] = first1[u];
     51     e1[ecnt1].u = u;
     52     e1[ecnt1].v = v;
     53     e1[ecnt1].cost = c;
     54     first1[u] = ecnt1;
     55 }
     56 
     57 void Add_edge2(int u,int v,int c){
     58     nxt2[++ecnt2] = first2[u];
     59     e2[ecnt2].v = v;
     60     e2[ecnt2].cost = c;
     61     first2[u] = ecnt2;
     62 }
     63 
     64 void Add_edge(int u,int v,int c){
     65     e[ecnt].next = first[u];
     66     e[ecnt].v = v;
     67     e[ecnt].u = u;
     68     e[ecnt].c = c;
     69     first[u] = ecnt++;
     70 }
     71 
     72 struct cmp{
     73     bool operator ()(pii a,pii b){
     74         return a.first > b.first;
     75     }
     76 };
     77 
     78 void Dijstra1(int s){
     79     priority_queue<pii,vector<pii >,cmp> PQ;
     80     dis1[s] = 0;
     81     PQ.push(MP(dis1[s],s));
     82     int cnt = 0;
     83     while(!PQ.empty()){
     84         pii x = PQ.top(); PQ.pop();
     85         if(dis1[x.second] < x.first) continue; 
     86         for(int i = first1[x.second]; i != -1; i = nxt1[i]){
     87             int v = e1[i].v;
     88             if(dis1[v] > dis1[x.second] + e1[i].cost){
     89                 dis1[v] = dis1[x.second] + e1[i].cost;
     90                 PQ.push(MP(dis1[v],v));
     91             }
     92         }
     93     }
     94 }
     95 
     96 void Dijstra2(int s){
     97     priority_queue<pii,vector<pii >,cmp> PQ;
     98     dis2[s] = 0;
     99     PQ.push(MP(dis2[s],s));
    100     int cnt = 0;
    101     while(!PQ.empty()){
    102         pii x = PQ.top(); PQ.pop();
    103         if(dis2[x.second] < x.first) continue; 
    104         for(int i = first2[x.second]; i != -1; i = nxt2[i]){
    105             int v = e2[i].v;
    106             if(dis2[v] > dis2[x.second] + e2[i].cost){
    107                 dis2[v] = dis2[x.second] + e2[i].cost;
    108                 PQ.push(MP(dis2[v],v));
    109             }
    110         }
    111     }
    112 }
    113 
    114 bool bfs(){
    115     queue<int> q;
    116     while(!q.empty()) q.pop();
    117     q.push(st);
    118     memset(lev,-1,sizeof(lev));
    119     lev[st] = 0;
    120     while(!q.empty()){
    121         int x = q.front();q.pop();
    122         for(int i = first[x];~i;i = e[i].next){
    123             int v = e[i].v;
    124             if(lev[v] < 0 && e[i].c > 0){
    125                 lev[v] = lev[x] + 1;
    126                 q.push(v);
    127             }
    128         }
    129     }
    130     return lev[ed] != -1;
    131 }
    132 
    133 int dfs(int p,int minf){
    134     if(p == ed || minf == 0) return minf;
    135     for(int &i = now[p];~i;i = e[i].next){
    136         int v = e[i].v;
    137         if(lev[v] == lev[p] + 1 && e[i].c > 0){
    138             int d = dfs(v,min(e[i].c,minf));
    139             if(d > 0){
    140                 e[i].c -= d;
    141                 e[i^1].c += d;
    142                 return d;
    143             }
    144         }
    145     }
    146     return 0;
    147 }
    148 
    149 int dinic(){
    150     int max_flow = 0,p1;
    151     while(bfs()){
    152         memcpy(now,first,sizeof(first));
    153         while((p1 = dfs(st,INF)) > 0)
    154         max_flow += p1;
    155     }
    156     return max_flow;
    157 }
    158 
    159 
    160 
    161 int main(){
    162     int a,b,c;
    163     int T;
    164     scanf("%d",&T);
    165     while(T--){
    166         scanf("%d %d",&n,&m);
    167         init();
    168         for(int i = 1; i <= m; ++i){
    169             scanf("%d%d%d",&a,&b,&c);
    170             Add_edge1(a,b,c);
    171             Add_edge2(b,a,c);
    172         }
    173         scanf("%d %d",&st,&ed);
    174         
    175         for(int i = 1;i <= n;i++) dis1[i] = dis2[i] = INF;
    176         
    177         Dijstra1(st);
    178         Dijstra2(ed);
    179         path = dis1[ed];
    180         
    181      //   for(int i = 1;i <= n;i++)
    182       //  printf("dis1[%d] = %d  dis2[%d] = %d
    ",i,dis1[i],i,dis2[i]);
    183         
    184         for(int u = 1;u <= n;u++){
    185             for(int i = first1[u];~i;i = nxt1[i]){
    186                 int v = e1[i].v;
    187                 if(dis1[u] + dis2[v] +e1[i].cost == path){
    188                 //    printf("u = %d  v = %d
    ",u,v);
    189                     Add_edge(u,v,1);
    190                     Add_edge(v,u,0);
    191                 }
    192             }
    193         }
    194         printf("%d
    ",dinic()); 
    195     }
    196     return 0;
    197 }
    View Code
  • 相关阅读:
    使用MobaXterm远程连接Ubuntu,启动Octave,界面不能正常显示
    ABP .Net Core 日志组件集成使用NLog
    ABP .Net Core Entity Framework迁移使用MySql数据库
    ABP前端使用阿里云angular2 UI框架NG-ZORRO分享
    阿里云 Angular 2 UI框架 NG-ZORRO介绍
    Visual Studio 2019 Window Form 本地打包发布猫腻
    VS Code + NWJS(Node-Webkit)0.14.7 + SQLite3 + Angular6 构建跨平台桌面应用
    ABP .Net Core 调用异步方法抛异常A second operation started on this context before a previous asynchronous operation completed
    ABP .Net Core To Json序列化配置
    .Net EF Core数据库使用SQL server 2008 R2分页报错How to avoid the “Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.”
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4726561.html
Copyright © 2011-2022 走看看