zoukankan      html  css  js  c++  java
  • POJ 1459 Power Network【SAP】


    http://poj.org/problem?id=1459
    POJ 1459 Power Network
    大意:已知供电站的最大供电量,消费者的最大消费量,电线传输电量的上限,
    求整个供电网的最大供电量
    算法核心:SAP

    #include<stdio.h>
    #include<string.h>
    const int N = 100+5;
    const int MAXN =N;
    const int INF = 20000+200+2;
    int S,T;//S为源点,T为汇点
    int graph[N][N];
    int getNum()
    {
     int num = 0;
     char c;
     while(c=getchar())
     {
      if(c<='9'&&c>='0')break;
     }
    
     while(c<='9'&&c>='0')
     {
      num=num*10+c-'0';
      c=getchar();
     }
     return num;
    }
    
    inline void addEdge(int s,int t,int flow)
    {
        graph[s][t]+=flow;
    }
    void init()
    {
     memset(graph,0,sizeof(graph));
    }
    
    int SAP(int map[][MAXN],int v_count,int s,int t)      //邻接矩阵,节点总数,始点,汇点   
    {   
     int i;   
     int cur_flow,max_flow,cur,min_label,temp;         //当前流,最大流,当前节点,最小标号,临时变量   
     char flag;                                        //标志当前是否有可行流   
     int cur_arc[MAXN],label[MAXN],neck[MAXN];         //当前弧,标号,瓶颈边的入点(姑且这么叫吧)   
     int label_count[MAXN],back_up[MAXN],pre[MAXN];    //标号为i节点的数量,cur_flow的纪录,当前流路径中前驱   
    
     //初始化   
     memset(label,0,MAXN*sizeof(int));   
     memset(label_count,0,MAXN*sizeof(int));   
    
     memset(cur_arc,0,MAXN*sizeof(int));   
     label_count[0]=v_count;                           //全部初始化为距离为0   
    
     neck[s]=s;   
     max_flow=0;   
     cur=s;   
     cur_flow=INF;   
    
     //循环代替递归   
     while(label[s]<v_count)   
     {   
      back_up[cur]=cur_flow;   
      flag=0;   
    
      //选择允许路径(此处还可用邻接表优化)   
      for(i=cur_arc[cur];i<v_count;i++)    //当前弧优化   
      {   
       if(map[cur][i]!=0&&label[cur]==label[i]+1)    //找到允许路径   
       {   
        flag=1;   
        cur_arc[cur]=i;    //更新当前弧   
        if(map[cur][i]<cur_flow)    //更新当前流   
        {   
         cur_flow=map[cur][i];   
         neck[i]=cur;     //瓶颈为当前节点   
        }   
        else 
        {   
         neck[i]=neck[cur];     //瓶颈相对前驱节点不变   
        }   
        pre[i]=cur;    //记录前驱   
        cur=i;   
        if(i==t)    //找到可行流   
        {   
         max_flow+=cur_flow;    //更新最大流   
    
         //修改残量网络   
         while(cur!=s)   
         {   
          if(map[pre[cur]][cur]!=INF)map[pre[cur]][cur]-=cur_flow;   
          back_up[cur] -= cur_flow;   
          if(map[cur][pre[cur]]!=INF)map[cur][pre[cur]]+=cur_flow;   
          cur=pre[cur];   
         }   
    
         //优化,瓶颈之后的节点出栈   
         cur=neck[t];   
         cur_flow=back_up[cur];    
        }   
        break;   
       }   
      }   
      if(flag)continue;   
    
      min_label=v_count-1;    //初始化min_label为节点总数-1   
    
      //找到相邻的标号最小的节点      
      for(i=0;i<v_count;i++)   
      {   
       if(map[cur][i]!=0&&label[i]<min_label)   
       {   
        min_label=label[i];   
        temp=i;   
       }   
      }   
      cur_arc[cur]=temp;    //记录当前弧,下次从提供最小标号的节点开始搜索   
      label_count[label[cur]]--;    //修改标号纪录   
      if(label_count[label[cur]]==0)break;    //GAP优化   
      label[cur]=min_label+1;    //修改当前节点标号   
      label_count[label[cur]]++;     //修改标号记录   
      if(cur!=s)   
      {   
       //从栈中弹出一个节点   
       cur=pre[cur];   
       cur_flow=back_up[cur];   
      }   
     }   
     return(max_flow);   
    }
    
    int main()
    {
     int n,np,nc,m;
     while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
     {
      S = n;
      T = n+1;
          init();
      int u,v,z;
      while(m--)
      {
           u=getNum();
        v=getNum();
        z=getNum();
        addEdge(u,v,z);
        addEdge(v,u,0);//添加反向边
        //printf("(%d %d)%d\n",u,v,z);
      }
    
        while(np--)
        {
          u = getNum();
          z = getNum();
       addEdge(S,u,z);
       addEdge(u,S,0);//反向弧
       //printf("(%d)%d\n",u,z);
        }
    
        while(nc--)
        {
              u = getNum();
        z = getNum();
        addEdge(u,T,z);
        addEdge(T,u,0);
        //printf("(%d)%d\n",u,z);
        }
        printf("%d\n",SAP(graph,T+1,S,T));
     }
     return 0;
    }
    
  • 相关阅读:
    巴科斯范式和sql语言
    mysql 视图
    1503
    mysql SQL_CALC_FOUND_ROWS
    create table xxx as select 与 create table xxx like
    mysql 1030 Got error 28 from storage engine
    python -- 装饰器入门
    12C新特性 -- 共享asm口令文件
    MySQL子查询的优化
    MySQL的explain
  • 原文地址:https://www.cnblogs.com/AndreMouche/p/1962319.html
Copyright © 2011-2022 走看看