首先弄明白题意要干嘛…… 在一个无向图中小偷要偷东西..小偷从s点出发..要偷的东在点e...警察可以用一些警力封锁一些点让小偷无论如何都不能到达e 求最小割
第一行的数字K,表示一共有这么多的警察,即最后的最大流不能超过这个数字。N星球个数,即点的个数。M:边的个数(最最原始,每两个点连着的边的个数)S: 起点 F:终点 下行每个点:每个星球所需警察数 再下面:连着的点对
如何建模是重点!据说最小割都是这么建模的,把一个点拆成两个 原来点上的权变成拆成两点间流的大小。最小割啊最小割~这么一说就明白了是不是~
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=100000;
const int maxe=1000000;
int sum,s,e,head[maxn],level[maxn],que[maxn],n,m;
struct node{
int w,to,next;
}edge[maxe];
inline void add(int u,int v,int c)
{
edge[sum].to=v;
edge[sum].w=c;
edge[sum].next=head[u];
head[u]=sum++;
edge[sum].to=u;
edge[sum].w=0;
edge[sum].next=head[v];
head[v]=sum++;
}
inline bool bfs()
{
memset(level,0,sizeof(level));
int p=0;
que[p++]=s;
level[s]=1;
for(int i=0;i<p;i++)
{
int temp=que[i];
for(int k=head[temp];k>-1;k=edge[k].next)
if(edge[k].w && (!level[edge[k].to])){
que[p++]=edge[k].to;
level[edge[k].to]=level[temp]+1;
}
}
return level[e];
}
int dfs(int now,int maxf)
{
if(now==e)return maxf;
int ret=0;
for(int i=head[now];i>-1 && ret<maxf; i=edge[i].next)
if(edge[i].w && (level[edge[i].to]==level[now]+1))
{
int temp=dfs(edge[i].to,min(maxf-ret,edge[i].w));
edge[i].w-=temp;
edge[i^1].w+=temp;
ret+=temp;
}
if(ret==0)level[now]=0;
return ret;
}
inline int dinic()
{
int ans=0;
while(bfs())ans+=dfs(s,inf);
return ans;
}
int main()
{
//freopen("cin.txt","r",stdin);
int k,w,a,b;
while(~scanf("%d",&k))
{
sum=0;
memset(head,-1,sizeof(head));
scanf("%d%d%d%d",&n,&m,&s,&e);
s=s<<1|1;
e=e<<1;
for(int i=1;i<=n;i++)
{
scanf("%d",&w);
add(i<<1,i<<1|1,w);
add(i<<1|1,i<<1,w);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
add(a<<1|1,b<<1,inf);
add(b<<1|1,a<<1,inf);
}
if(dinic()<=k && s!=e+1 && s!=e-1 && s!=e) puts("YES");
else puts("NO");
}
return 0;
}