zoukankan      html  css  js  c++  java
  • poj 2455

    题意:由一个点走到另一个点,中间的点可以重复到达,但边只能经过一次,问T条边不重复的路径里,最长的边的最小值.

    分析:由于点是可以重用的,因此不必拆点.这道题有重边,而且重边都必须保留,因为点是可以重复走的.二分最长的边长,用最大流来验证.

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 const int MAXN=205;//点数的最大值
      5 const int MAXM=160005;//边数的最大值
      6 const int INF=0x3fffffff;
      7 
      8 struct Node
      9 {
     10     int from,to,next;
     11     int cap;
     12 }edge[MAXM];
     13 
     14 int tol;
     15 int head[MAXN];
     16 int dep[MAXN];
     17 int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
     18 int n;//n是总的点的个数,包括源点和汇点
     19 Node container[40005];
     20 
     21 void init()
     22 {
     23     tol=0;
     24     memset(head,-1,sizeof(head));
     25 }
     26 
     27 void addedge(int u,int v,int w)
     28 {
     29     edge[tol].from=u;
     30     edge[tol].to=v;
     31     edge[tol].cap=w;
     32     edge[tol].next=head[u];
     33     head[u]=tol++;
     34     edge[tol].from=v;
     35     edge[tol].to=u;
     36     edge[tol].cap=0;
     37     edge[tol].next=head[v];
     38     head[v]=tol++;
     39 }
     40 void BFS(int start,int end)
     41 {
     42     memset(dep,-1,sizeof(dep));
     43     memset(gap,0,sizeof(gap));
     44     gap[0]=1;
     45     int que[MAXN];
     46     int front,rear;
     47     front=rear=0;
     48     dep[end]=0;
     49     que[rear++]=end;
     50     while(front!=rear)
     51     {
     52         int u=que[front++];
     53         if(front==MAXN)front=0;
     54         for(int i=head[u];i!=-1;i=edge[i].next)
     55         {
     56             int v=edge[i].to;
     57             if(dep[v]!=-1)continue;
     58             que[rear++]=v;
     59             if(rear==MAXN)rear=0;
     60             dep[v]=dep[u]+1;
     61             ++gap[dep[v]];
     62         }
     63     }
     64 }
     65 int SAP(int start,int end)
     66 {
     67     int res=0;
     68     BFS(start,end);
     69     int cur[MAXN];
     70     int S[MAXN];
     71     int top=0;
     72     memcpy(cur,head,sizeof(head));
     73     int u=start;
     74     int i;
     75     while(dep[start]<n)
     76     {
     77         if(u==end)
     78         {
     79             int temp=INF;
     80             int inser;
     81             for(i=0;i<top;i++)
     82                if(temp>edge[S[i]].cap)
     83                {
     84                    temp=edge[S[i]].cap;
     85                    inser=i;
     86                }
     87             for(i=0;i<top;i++)
     88             {
     89                 edge[S[i]].cap-=temp;
     90                 edge[S[i]^1].cap+=temp;
     91             }
     92             res+=temp;
     93             top=inser;
     94             u=edge[S[top]].from;
     95         }
     96         if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路
     97           break;
     98         for(i=cur[u];i!=-1;i=edge[i].next)
     99            if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
    100              break;
    101         if(i!=-1)
    102         {
    103             cur[u]=i;
    104             S[top++]=i;
    105             u=edge[i].to;
    106         }
    107         else
    108         {
    109             int min=n;
    110             for(i=head[u];i!=-1;i=edge[i].next)
    111             {
    112                 if(edge[i].cap==0)continue;
    113                 if(min>dep[edge[i].to])
    114                 {
    115                     min=dep[edge[i].to];
    116                     cur[u]=i;
    117                 }
    118             }
    119             --gap[dep[u]];
    120             dep[u]=min+1;
    121             ++gap[dep[u]];
    122             if(u!=start)u=edge[S[--top]].from;
    123         }
    124     }
    125     return res;
    126 }
    127 int main()
    128 {
    129     int N,P,T;
    130     while(~scanf("%d%d%d",&N,&P,&T))
    131     {
    132         n = N;
    133         int left = INF,right = 0;
    134         for(int i = 0;i < P;i++)
    135         {
    136             scanf("%d%d%d",&container[i].from,&container[i].to,&container[i].cap);
    137             left = std::min(container[i].cap,left);
    138             right = std::max(container[i].cap,right);
    139         }
    140         left--;
    141         while(left + 1 < right)
    142         {
    143             int mid = (left + right) / 2;
    144             init();
    145             for(int i = 0;i < P;i++)
    146             {
    147                 if(container[i].cap <= mid)
    148                 {
    149                     addedge(container[i].from,container[i].to,1);
    150                     addedge(container[i].to,container[i].from,1);
    151                 }
    152             }
    153             if(SAP(1,n) >= T)
    154             {
    155                 right = mid;
    156             }
    157             else
    158             {
    159                 left = mid;
    160             }
    161         }
    162         printf("%d
    ",right);
    163     }
    164     return 0;
    165 }
  • 相关阅读:
    CCOrbitCamera卡牌翻转效果
    用CCRenderTexture和BlendFunc制作游戏教学时使用的黑色覆盖层
    cocos2d-x触摸分发器原理
    cocos2d-x动作原理
    c++之函数原型
    cocos2d-x调度器原理
    cocos2d-x之MoonWarriors用c++实现
    cocos2d-x回收池原理
    SQL*Net more data to client等待事件
    asynch descriptor resize等待事件
  • 原文地址:https://www.cnblogs.com/ZShogg/p/3234253.html
Copyright © 2011-2022 走看看