• Power Network POJ


      1 #include<cstring>
      2 #include<cstdio>
      3 #define FOR(i,f_start,f_end) for(int i=f_startl;i<=f_end;i++)
      4 #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
      5 const int maxn=500;
      6 const int maxm=2e4+5;
      7 int size;
      8 int n;
      9 const int inf=0x3f3f3f3f;
     10 using namespace std;
     11 int head[maxn];
     12 void init(){
     13     size=0;
     14     MS(head,-1);
     15 }
     16 struct Node{
     17     int from,to,cap,next;
     18 }edge[maxn];
     19 void add(int u,int v,int w){
     20     edge[size].from=u;
     21     edge[size].to=v;
     22     edge[size].cap=w;
     23     edge[size].next=head[u];
     24     head[u]=size++;
     25     edge[size].from=v;
     26     edge[size].to=u;
     27     edge[size].cap=0;
     28     edge[size].next=head[v];
     29     head[v]=size++;
     30 }
     31 int dep[maxn];
     32 int bfs(int start,int end){
     33     int que[maxn];
     34     int front,rear;
     35     MS(dep,-1);
     36     que[rear++]=start;
     37     dep[start]=0;
     38     while(front!=rear){
     39         int u=que[front++];
     40         if(front==maxn)front=0;
     41         for(int i=head[u];i!=-1;i=edge[i].next){
     42             int v=edge[i].to;
     43             if(edge[i].cap>0&&dep[v]==-1){
     44                 dep[v]=dep[u]+1;
     45                 que[rear++]=v;
     46                 if(rear>=maxn)rear=0;
     47                 if(v==end)return 1;//优化1 找到直接返回
     48             }
     49         }
     50     }
     51     return 0;
     52 
     53 }
     54 int dinic(int start,int end){
     55 
     56     int res=0;
     57     int top;
     58     int stack[maxn];//非递归 手写栈
     59     int cur[maxn];
     60     while(bfs(start,end)){
     61         memcpy(cur,head,sizeof(head));//当前弧预备工作
     62         int u=start;
     63         top=0;
     64         while(1){
     65             if(u==end){//当找到终点的时候
     66             int min=inf;
     67             int loc;
     68             for(int i=0;i<top;i++){//找到路径里面最小的流量
     69                 if(min>edge[stack[i]].cap){
     70                     min=edge[stack[i]].cap;
     71                     loc=i;//记下最小流量的边 之后的点都不可能到达了
     72                 }
     73             }
     74             for(int i=0;i<top;i++){//减流量和加反向边
     75                 edge[stack[i]].cap-=min;
     76                 edge[stack[i]^1].cap+=min;
     77             }
     78             res+=min;
     79             top=loc;//退栈顶到那个流量已经清零的边的起点i
     80             u=edge[stack[top]].from;
     81         
     82               }
     83             for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)//当前弧优化如果存在以下情况的时候就可以break进行操作了
     84                 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to])
     85                     break;
     86             if(cur[u]!=-1){//如果有边可以走 那么就把边和点入栈
     87                 stack[top++]=cur[u];
     88                 u=edge[cur[u]].to;
     89             }
     90             else {//如果从栈顶点出发找不到可以增广的路径了,那么如果栈已经空了 那可能就没有可以增广的路径了,而如果栈没有空 那么就退栈继续找
     91                 if(top==0)break;
     92                 dep[u]=-1;//因为从u已经找不到可以走的路径了 直接把dep[u]=-1相当于没有点可以可以通过dep[u]+1==dep[edge[i].to]的条件 也就是u以后也入不了栈了
     93                 u=edge[stack[--top]].from;
     94             }
     95         }
     96     }
     97     return res;
     98 }
     99 int main(){
    100     int start,end;
    101     int np,nc,m;
    102     int u,v,z;
    103     while(scanf("%d%d%d%d",&n,&np,&nc,&m)==4){
    104         init();
    105     while(m--){
    106         while(getchar()!='(');
    107         scanf("%d,%d)%d",&u,&v,&z);
    108         u++,v++;
    109         add(u,v,z);
    110         
    111     }
    112     while(np--){
    113         while(getchar()!='(');
    114         scanf("%d)%d",&u,&z);
    115         u++;
    116         add(0,u,z);
    117     }
    118     while(nc--){
    119         while(getchar()!='(');
    120         scanf("%d)%d",&u,&v);
    121         u++;
    122         add(u,n+1,z);
    123     }
    124     start=0;
    125     end=n+1;
    126     int ans=dinic(start,end);
    127     printf("%d
    ",ans);
    128     }
    129 return 0;
    130 }
  • 相关阅读:
    leetcode整理(一)
    day02 整理
    python从入门到放弃之守护进程
    python从入门到放弃之进程
    基于hashlib下的文件校验
    hashlib(hmac)进阶之client跟server交互
    hashlib以及hmac的日常应用
    python从入门到放弃
    6.redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?
    5.如何保证 redis 的高并发和高可用?redis 的主从复制原理能介绍一下么?redis 的哨兵原理能介绍一下么?
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/10548211.html
Copyright © 2020-2023  润新知