HDOJ 3987 - Harry Potter and the Forbidden Forest 设置偏移量,最小割

                    题意:

                             食死徒要从0号点走到n-1号点...HP要组织他们过去..所以要用法力来切断路..有些路是单向的有些路是双向的..每条路有各自的切断法力值..现在问让食死徒无法到达n-1..并且所需的法力值最小..并且切断的路最少为多少...

                    题解:

                             这种维护优先级的最优值..so easy.加偏移量就是..由于边数最多10^5..那么就把偏移量设置为比其大的就行了..我设的偏移量为2*10^5....注意的是加了偏移量后..流量会超int..那么与流量有关的变量都要设置为long long..特别注意的是流量初始的最大值..也要相应的扩大...


Program:

#include<iostream>    
#include<algorithm>    
#include<stdio.h>    
#include<string.h>  
#include<time.h> 
#include<map> 
#include<math.h>    
#include<queue>    
#define MAXN 1505 
#define MAXM 800005
#define key (ll)200000
#define oo (ll)1000000007*(ll)1000000007    
#define ll long long    
using namespace std;   
struct Dinic            
{            
       struct node          
       {           
             int u,v,next;
             ll c;          
       }edge[MAXM];          
       int ne,head[MAXN];         
       int cur[MAXN],ps[MAXN],dep[MAXN];
       bool mark[MAXN];          
       void initial()          
       {          
             ne=2;       
             memset(head,0,sizeof(head));  
       }          
       void addedge(int u,int v,ll c)          
       {           
             edge[ne].u=u,edge[ne].v=v,edge[ne].c=c,edge[ne].next=head[u];   
             head[u]=ne++;      
             edge[ne].u=v,edge[ne].v=u,edge[ne].c=0,edge[ne].next=head[v];          
             head[v]=ne++;          
       }     
       void dfs(int x)
       {
             mark[x]=true;
             for (int k=head[x];k;k=edge[k].next)
                 if (!mark[edge[k].v] && edge[k].c) 
                     dfs(edge[k].v);
       }
       ll MaxFlow(int s,int t)          
       {                               
             ll tr,res=0,f;
             int i,j,k,r,top;          
             while(1)          
             {          
                    memset(dep, -1, sizeof(dep));          
                    for(f=dep[ps[0]=s]=0,r=1;f!= r;)          
                       for(i=ps[f++],j=head[i];j;j=edge[j].next)          
                         if(edge[j].c&&dep[k=edge[j].v]==-1)          
                         {          
                               dep[k]=dep[i]+1;          
                               ps[r++]=k;          
                               if(k == t){  f=r; break;  }          
                         }          
                    if(dep[t]==-1) break;          
                    memcpy(cur,head,sizeof(cur));          
                    i=s,top=0;          
                    while(1)          
                    {          
                         if(i==t)          
                         {          
                               for(tr=oo,k=0;k<top;k++)          
                                  if(edge[ps[k]].c<tr)          
                                     tr=edge[ps[f=k]].c;          
                               for(k=0;k<top;k++)          
                               {          
                                     edge[ps[k]].c-=tr;          
                                     edge[ps[k]^1].c+=tr;          
                               }          
                               i=edge[ps[top=f]].u;          
                               res+= tr;          
                         }          
                         for(j=cur[i];cur[i];j=cur[i]=edge[cur[i]].next)           
                             if(edge[j].c && dep[i]+1==dep[edge[j].v]) break;           
                         if(cur[i])  ps[top++]=cur[i],i=edge[cur[i]].v;           
                         else          
                         {          
                                 if(!top) break;          
                                 dep[i]=-1;          
                                 i=edge[ps[--top]].u;          
                         }          
                   }          
             }       
             return res;          
      }          
}T;        
int main()   
{     
      int C,cases,n,m,s,e,u,v,d;
      ll c; 
      scanf("%d",&C); 
      for (cases=1;cases<=C;cases++)
      {
               scanf("%d%d",&n,&m);
               s=0,e=n-1,T.initial();
               while (m--)
               {
                       scanf("%d%d%I64d%d",&u,&v,&c,&d),c=c*key+1;
                       T.addedge(u,v,c);
                       if (d) T.addedge(v,u,c);
               }
               printf("Case %d: %I64d\n",cases,T.MaxFlow(s,e)%key);
      }  
      return 0;  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值