• HDU 3416 Marriage Match IV


    题意:给出一张n个点m条边的无向图( 2<=n<=1000, 0<=m<=100000 )和起点S、终点T。现在要求你每次从S出发都使用一条最短路到达T,并且每条路只能走一次。问最多可以从S走到T走几次最短路。

    先处理出S到所有点的最短路,假设S到点i的最短路为d[i]。枚举每条边(from,to,cost),如果d[to]=d[from]+cost,在新图中加一条边(from,to,1),完了之后从S到T跑最大流。

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #define INF 1<<30
      7 #define maxn 1010
      8 #define maxm 300000
      9 using namespace std;
     10 typedef pair<int,int> pii;
     11 int v[maxm],next[maxm],w[maxm];
     12 int first[maxn],d[maxn],work[maxn],q[maxn];
     13 int e,S,T,N,M;
     14 struct Edge{
     15     int from,to,dist;
     16 }edge[100010];
     17 
     18 void init(){
     19     e = 0;
     20     memset(first,-1,sizeof(first));
     21 }
     22 
     23 void add_edge1(int a,int b,int c){
     24     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
     25 }
     26 
     27 void add_edge2(int a,int b,int c){
     28     //printf("add:%d to %d,cap = %d
    ",a,b,c);
     29     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
     30     v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
     31 }
     32 
     33 void dijkstra(int src){
     34     priority_queue <pii,vector<pii>,greater<pii> > q;
     35     memset(d,-1,sizeof(d));
     36     d[src] = 0;
     37     q.push(make_pair(0,src));
     38     while(!q.empty()){
     39         while(!q.empty() && q.top().first > d[q.top().second])  q.pop();
     40         if(q.empty())   break;
     41         int u = q.top().second;
     42         q.pop();
     43         for(int i = first[u];i != -1;i = next[i]){
     44             if(d[v[i]] > d[u] + w[i] || d[v[i]] == -1){
     45                 d[v[i]] = d[u] + w[i];
     46                 q.push(make_pair(d[v[i]],v[i]));
     47             }
     48         }
     49     }
     50 }
     51 
     52 int bfs(){
     53     int rear = 0;
     54     memset(d,-1,sizeof(d));
     55     d[S] = 0;q[rear++] = S;
     56     for(int i = 0;i < rear;i++){
     57         for(int j = first[q[i]];j != -1;j = next[j])
     58             if(w[j] && d[v[j]] == -1){
     59                 d[v[j]] = d[q[i]] + 1;
     60                 q[rear++] = v[j];
     61                 if(v[j] == T)   return 1;
     62             }
     63     }
     64     return 0;
     65 }
     66 
     67 int dfs(int cur,int a){
     68     if(cur == T)    return a;
     69     for(int &i = work[cur];i != -1;i = next[i]){
     70         if(w[i] && d[v[i]] == d[cur] + 1)
     71             if(int t = dfs(v[i],min(a,w[i]))){
     72                 w[i] -= t;w[i^1] += t;
     73                 return t;
     74             }
     75     }
     76     return 0;
     77 }
     78 
     79 int dinic(){
     80     int ans = 0;
     81     while(bfs()){
     82         memcpy(work,first,sizeof(first));
     83         while(int t = dfs(S,INF))   ans += t;
     84     }
     85     return ans;
     86 }
     87 
     88 int main()
     89 {
     90     int kase;
     91     scanf("%d",&kase);
     92     while(kase--){
     93         init();
     94         scanf("%d%d",&N,&M);
     95         for(int i = 0;i < M;i++){
     96             int a,b,c;
     97             scanf("%d%d%d",&a,&b,&c);
     98             add_edge1(a,b,c);
     99             edge[i].from = a;
    100             edge[i].to = b;
    101             edge[i].dist = c;
    102         }
    103         scanf("%d%d",&S,&T);
    104         dijkstra(S);
    105         //for(int i = 1;i <= N;i++)
    106         //    printf("d[%d] = %d
    ",i,d[i]);
    107         init();
    108         for(int i = 0;i < M;i++){
    109             int from = edge[i].from;
    110             int to = edge[i].to;
    111             int dist = edge[i].dist;
    112             if(d[to] == d[from] + dist)
    113                 add_edge2(from,to,1);
    114         }
    115         int ans = dinic();
    116         printf("%d
    ",ans);
    117     }
    118     return 0;
    119 }
    View Code
  • 相关阅读:
    2016.11.9 小测试
    【noip】跟着洛谷刷noip题2
    【长沙集训】2017.10.10
    【noip】跟着洛谷刷noip题
    Oracle-函数-translate
    bit,byte,char,string区别与基本类型认识
    通俗地讲,Netty 能做什么?
    oracle判断一个字符串中是否包含另外一个字符串
    Oracle导入导出数据库(exp/imp和expdp/impdp的区别)
    同步异步以及阻塞和非阻塞的区别
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3391176.html
Copyright © 2020-2023  润新知