这i题我一直在想点和边进行建图,真tm的sb,这样根本没办法保证一条边和它的两个点都选上了,其实应该就点和点连边,每个点拆成i和i',源点和i连一条权值为di的边,i'和汇点连一条权值为di的边,对于m条边,u和v,u于v'建边,v与u'建边,这样每个点的流量都只能流到其他点,最大流就是让每个点都选了di条边,只要源点汇点流量等于di的和就是答案了
(这题正解是带花树,如果重测了到时候再改成带花树
虽然牛客不负责任的没有重测,但是我还是来补一下带花树的正解
链接:https://ac.nowcoder.com/acm/contest/5666/I
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
Bobo has a graph with n vertices and m edges where the i-th edge is between the vertices aia_iai and bib_ibi. Find out whether is possible for him to choose some of the edges such that the i-th vertex is incident with exactly did_idi edges.
The input consists of several test cases terminated by end-of-file.
The first line of each test case contains two integers n and m.
The second line contains n integers d1,d2,…,dnd_1, d_2, \dots, d_nd1,d2,…,dn.
The i-th of the following m lines contains two integers aia_iai and bib_ibi.
* 1≤n≤501 \leq n \leq 501≤n≤50
* 1≤m≤1001 \leq m \leq 1001≤m≤100
* 1≤di≤21 \leq d_i \leq 21≤di≤2
* 1≤ai,bi≤n1 \leq a_i, b_i \leq n1≤ai,bi≤n
* ai≠bia_i \neq b_iai=bi
* {ai,bi}≠{aj,bj}\{a_i, b_i\} \neq \{a_j, b_j\}{ai,bi}={aj,bj} for i≠ji \neq ji=j
* The number of tests does not exceed 100.
For each test case, print "`Yes`" without quotes if it is possible. Otherwise, print "`No`" without quotes.
示例1
复制2 1 1 1 1 2 2 1 2 2 1 2 3 2 1 1 2 1 3 2 3
2 1
1 1
1 2
2 1
2 2
1 2
3 2
1 1 2
1 3
2 3
复制Yes No Yes
Yes
No
Yes
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define inf 1e9
#define maxn 1005
#define maxm 105000
struct Edge{
int to,next,flow;
} e[maxm];
int d1[maxn],n,m,head[maxn],cur[maxn],cnt,st,ed;
void add(int u,int v,int flow)
{
e[cnt] = (Edge)
{
v, head[u], flow
};
head[u] = cnt++;
e[cnt] = (Edge)
{
u, head[v], 0
};
head[v] = cnt++;
}
void init()
{
cnt=0;
st=0;
ed=2*n+1;
memset(head,-1,sizeof(head));
}
int dfs(int now,int ed,int lim)
{
if(now==ed||!lim)
{
return lim;
}
int flow=0,f1;
for(int i=cur[now]; i!=-1; i=e[i].next)
{
cur[now]=i;
int v=e[i].to;
if(d1[v]==d1[now]+1&&(f1=dfs(v,ed,min(e[i].flow,lim))))
{
flow+=f1;
lim-=f1;
e[i].flow-=f1;
e[i^1].flow+=f1;
if(!lim)
break;
}
}
return flow;
}
int bfs(int st,int ed)
{
for(int i=0; i<=ed; i++)
{
cur[i]=head[i];
d1[i]=0x7f7f7f7f;
}
queueq;
d1[st]=0;
q.push(st);
while(!q.empty())
{
int u=q.front();
q.pop();
//printf("u=%d\n",u);
for(int i=head[u]; i!=-1; i=e[i].next)
{
int v=e[i].to;
//printf(" d[%d]=%d e[i].flow=%d\n",v,d[v],e[i].flow);
if(d1[v]>inf&&e[i].flow)
{
d1[v]=d1[u]+1;
q.push(v);
}
}
}
if(d1[ed]