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
  • 相关阅读:
    OpenGL的glTranslatef平移变换函数详解
    OpenGL的glRotatef旋转变换函数详解
    OpenGL的GLUT初始化函数[转]
    OpenGL的GLUT事件处理(Event Processing)窗口管理(Window Management)函数[转]
    OpenGL的GLUT注册回调函数[转]
    OpenGL的gluLookAt和glOrtho的关系
    OpenGL的glClearColor和glClear改变背景颜色
    OpenGL的gluPerspective和gluLookAt的关系[转]
    OpenGL的glOrtho平行投影函数详解[转]
    OpenGL的glViewport视口变换函数详解[转]
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4726561.html
Copyright © 2011-2022 走看看