HDU 4280 Island Transport(网络…

来源:互联网 发布:ar9565 linux 编辑:程序博客网 时间:2024/06/11 10:08
题意:有N个岛屿 M条无向路 每个路有一最大允许的客流量,求从最西的那个岛屿最多能运用多少乘客到最东的那个岛屿。

思路:很单纯的网络流,重点是卡时间 模板的高效性很重要啊该模板详解 参见这里  模板题就不注释了

//4796MS   8836K

#include <stdio.h>
#include <string.h>
#define VM 100010
#define EM 400010
const int inf = 0x3f3f3f3f;
struct E
{
    int to, frm,nxt, cap;
}edge[EM];

int head[VM],e,n,m,src,des;
int dep[VM], gap[VM];

void addedge(int cu, int cv, int cw)
{
    edge[e].frm= cu;
    edge[e].to =cv;
    edge[e].cap= cw;
    edge[e].nxt= head[cu];
    head[cu] =e++;
    edge[e].frm= cv;
    edge[e].to =cu;
    edge[e].cap= 0;
    edge[e].nxt= head[cv];
    head[cv] =e++;
}

int que[VM];

void BFS()
{
    memset(dep,-1, sizeof(dep));
    memset(gap,0, sizeof(gap));
    gap[0] =1;
    int front =0, rear = 0;
    dep[des] =0;
    que[rear++]= des;
    int u,v;
    while (front!= rear)
    {
       u =que[front++];
       front =front%VM;
       for (inti=head[u]; i!=-1; i=edge[i].nxt)
       {
          v =edge[i].to;
          if(edge[i].cap != 0 || dep[v] != -1)
            continue;
          que[rear++]= v;
          rear = rear% VM;
          ++gap[dep[v]= dep[u] + 1];
       }
    }
}
int cur[VM],stack[VM];
intSap()      //sap模板
{
    int res =0;
    BFS();
    int top =0;
    memcpy(cur,head, sizeof(head));
    int u = src,i;
    while(dep[src] < n)
    {
       if (u ==des)
       {
          int temp =inf, inser = n;
          for (i=0;i!=top; ++i)
             if (temp> edge[stack[i]].cap)
             {
                temp =edge[stack[i]].cap;
                inser =i;
             }
          for (i=0;i!=top; ++i)
          {
            edge[stack[i]].cap -= temp;
            edge[stack[i]^1].cap += temp;
          }
          res +=temp;
          top =inser;
          u =edge[stack[top]].frm;
       }

       if (u != des&& gap[dep[u] -1] == 0)
          break;
       for (i =cur[u]; i != -1; i = edge[i].nxt)
          if(edge[i].cap != 0 && dep[u] ==dep[edge[i].to] + 1)
             break;

       if (i !=-1)
       {
          cur[u] =i;
          stack[top++]= i;
          u =edge[i].to;
       }
       else
       {
          int min =n;
          for (i =head[u]; i != -1; i = edge[i].nxt)
          {
             if(edge[i].cap == 0)
               continue;
             if (min> dep[edge[i].to])
             {
                min =dep[edge[i].to];
                cur[u] =i;
             }
          }
         --gap[dep[u]];
          ++gap[dep[u]= min + 1];
          if (u !=src)
             u =edge[stack[--top]].frm;
       }
    }
    returnres;
}

int main()
{
    int T,i;
    scanf("%d",&T);
    while(T--)
    {
      scanf("%d%d", &n, &m);
       int x,y;
       int Min =inf, Max = -inf;
       for (i=1;i<=n;++i)      //找出起点src 终点des
       {
         scanf("%d%d", &x, &y);
          if (x<= Min)
          {
             src =i;
             Min =x;
          }
          if (x>= Max)
          {
             des =i;
             Max =x;
          }
       }
       e = 0;
       memset(head,-1, sizeof(head));
       int u, v,c;
       for (i=0;i!=m; ++i)
       {
         scanf("%d%d%d", &u, &v,&c);
         addedge(u,v,c);
         addedge(v,u,c);
       }
       int ans =Sap();
      printf("%d\n", ans);
    }
    return0;
}

原创粉丝点击