zoukankan      html  css  js  c++  java
  • hdu 3599(最短路+最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3599

    思路:首先spfa求一下最短路,然后对于满足最短路上的边(dist[v]==dist[u]+w)加入到新图中来,边容量为1,最后求出的最大流就是没有相交的边的最短路径条数。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<string>
      4 #include<algorithm>
      5 #include<vector>
      6 #include<queue>
      7 using namespace std;
      8 #define MAXN 4444
      9 #define inf 1<<30
     10 
     11 struct Node{
     12     int v,w;
     13     Node(int vv,int ww):v(vv),w(ww){};
     14 };
     15 
     16 int n;
     17 bool mark[MAXN];
     18 int dist[MAXN];
     19 vector<vector<Node> >G;
     20 void spfa()
     21 {
     22     memset(mark,false,sizeof(mark));
     23     fill(dist,dist+n+2,inf);
     24     dist[1]=0;
     25     queue<int>que;
     26     que.push(1);
     27     while(!que.empty()){
     28         int u=que.front();
     29         que.pop();
     30         mark[u]=false;
     31         for(int i=0;i<G[u].size();i++){
     32             int v=G[u][i].v;
     33             int w=G[u][i].w;
     34             if(dist[u]+w<dist[v]){
     35                 dist[v]=dist[u]+w;
     36                 if(!mark[v]){
     37                     mark[v]=true;
     38                     que.push(v);
     39                 }
     40             }
     41         }
     42     }
     43 }
     44 
     45 struct Edge{
     46     int v,cap,next;
     47 }edge[MAXN*MAXN];
     48 
     49 int NE,NV;
     50 int head[MAXN];
     51 
     52 void Insert(int u,int v,int cap)
     53 {
     54     edge[NE].v=v;
     55     edge[NE].cap=cap;
     56     edge[NE].next=head[u];
     57     head[u]=NE++;
     58 
     59     edge[NE].v=u;
     60     edge[NE].cap=0;
     61     edge[NE].next=head[v];
     62     head[v]=NE++;
     63 }
     64 
     65 void Build()
     66 {
     67     NE=0;
     68     NV=n;
     69     memset(head,-1,sizeof(head));
     70     for(int u=1;u<=n;u++){
     71         for(int i=0;i<G[u].size();i++){
     72             int v=G[u][i].v,w=G[u][i].w;
     73             if(dist[u]+w==dist[v]){
     74                 Insert(u,v,1);
     75             }
     76         }
     77     }
     78 }
     79 
     80 int level[MAXN],gap[MAXN];
     81 void bfs(int vt)
     82 {
     83     memset(level,-1,sizeof(level));
     84     memset(gap,0,sizeof(gap));
     85     queue<int>que;
     86     que.push(vt);
     87     level[vt]=0;
     88     gap[level[vt]]++;
     89     while(!que.empty()){
     90         int u=que.front();
     91         que.pop();
     92         for(int i=head[u];i!=-1;i=edge[i].next){
     93             int v=edge[i].v;
     94             if(level[v]!=-1)continue;
     95             level[v]=level[u]+1;
     96             gap[level[v]]++;
     97             que.push(v);
     98         }
     99     }
    100 }
    101 
    102 int pre[MAXN],cur[MAXN];
    103 int SAP(int vs,int vt)
    104 {
    105     bfs(vt);
    106     memset(pre,-1,sizeof(pre));
    107     memcpy(cur,head,sizeof(head));
    108     int u=pre[vs]=vs,aug=inf,maxflow=0;
    109     gap[0]=NV;
    110     while(level[vs]<NV){
    111         bool flag=false;
    112         for(int &i=cur[u];i!=-1;i=edge[i].next){
    113             int v=edge[i].v;
    114             if(edge[i].cap>0&&level[u]==level[v]+1){
    115                 flag=true;
    116                 aug=min(aug,edge[i].cap);
    117                 pre[v]=u;
    118                 u=v;
    119                 if(v==vt){
    120                     maxflow+=aug;
    121                     for(u=pre[v];v!=vs;v=u,u=pre[u]){
    122                         edge[cur[u]].cap-=aug;
    123                         edge[cur[u]^1].cap+=aug;
    124                     }
    125                     aug=inf;
    126                 }
    127                 break;
    128             }
    129         }
    130         if(flag)continue;
    131         int minlevel=NV;
    132         for(int i=head[u];i!=-1;i=edge[i].next){
    133             int v=edge[i].v;
    134             if(edge[i].cap>0&&level[v]<minlevel){
    135                 minlevel=level[v];
    136                 cur[u]=i;
    137             }
    138         }
    139         if(--gap[level[u]]==0)break;
    140         level[u]=minlevel+1;
    141         gap[level[u]]++;
    142         u=pre[u];
    143     }
    144     return maxflow;
    145 }
    146 
    147 
    148 int main()
    149 {
    150     int _case,u,v,w;
    151     scanf("%d",&_case);
    152     while(_case--){
    153         scanf("%d",&n);
    154         G.clear();
    155         G.resize(n+2);
    156         while(true){
    157             scanf("%d%d%d",&u,&v,&w);
    158             if(u==0&&v==0&&w==0)break;
    159             G[u].push_back(Node(v,w));
    160             G[v].push_back(Node(u,w));
    161         }
    162         spfa();
    163         if(dist[n]==inf||n==1){
    164             puts("0");
    165             continue;
    166         }
    167         Build();
    168         printf("%d
    ",SAP(1,n));
    169     }
    170     return 0;
    171 }
    View Code
  • 相关阅读:
    Linux下分析某个进程CPU占用率高的原因
    Linux下查看某一进程所占用内存的方法
    jbd2导致系统IO使用率高问题
    Linux iotop命令详解
    1.Redis详解(一)------ redis的简介与安装
    Redis详解(十三)------ Redis布隆过滤器
    12.Redis详解(十二)------ 缓存穿透、缓存击穿、缓存雪崩
    面试问题总结
    算法与数据结构基础<二>----排序基础之插入排序法
    CarSim、Adams、Cruise和Simulink四款仿真软件的对比
  • 原文地址:https://www.cnblogs.com/wally/p/3307306.html
Copyright © 2011-2022 走看看