720A
贪心,把从(0,0)开始的人按距离从小到大排序,然后按顺序枚举所有人,尽量往下,在保证这个的前提下尽量往左。
这样可以将从(0,0)开始的人都填进去,然后把空位置按到(0,m+1)的距离排序,验证一下(0,m+1)的人是否都能填进去。
#include <bits/stdc++.h>
using namespace std;
int n,m,k,l;
int v1[11000],v2[11000],st[11000],top;
bool a[10001][10001];
int main()
{
//freopen("tt.in","r",stdin);
scanf("%d%d",&n,&m);
scanf("%d",&k);
for(int i=1;i<=k;i++)
scanf("%d",&v1[i]);
sort(v1+1,v1+1+k);
for(int i=1;i<=k;i++)
{
if(v1[i]<2)
{puts("NO");return 0;}
int flag=1;
for(int j=n;j>=1;j--)
{
for(int t=1;t<=m;t++)
{
if(j+t>v1[i])break;
if(!a[j][t])
{
a[j][t]=1;flag=0;
break;
}
}
if(!flag)break;
}
if(flag)
{puts("NO");return 0;}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!a[i][j])
st[++top]=i+m+1-j;
sort(st+1,st+1+top);
scanf("%d",&l);
for(int i=1;i<=l;i++)
scanf("%d",&v2[i]);
sort(v2+1,v2+1+l);
for(int i=1;i<=l;i++)
if(v2[i]<st[i])
{puts("NO");return 0;}
puts("YES");
return 0;
}
720B
网络流,建一个二分图,左侧每个环和不在环上的边建一个点。S连环流量为环大小-1,连不在环上的边流量1。右侧m个点代表每一个颜色。每个点连T流量为1。
如果环或边有某个颜色那么连一条流量1的边。
直接跑最大流就是答案。。。
#include <bits/stdc++.h>
using namespace std;
#define N 41000
#define M 110000
#define inf 1e9
int n,m;
struct network
{
int head[N],nex[M],to[M],val[M],tot;
int S,T,cnt,deep[N];
queue<int>que;
void add(int x,int y,int z)
{
tot++;
nex[tot]=head[x];head[x]=tot;
to[tot]=y;val[tot]=z;
}
void ade(int x,int y,int z)
{add(x,y,z);add(y,x,0);}
void init()
{
tot=1;S=m+1;T=m+2;
cnt=m+2;
for(int i=1;i<=m;i++)
ade(i,T,1);
}
int dfs(int x,int mv)
{
if(x==T)return mv;
int tmp=0;
for(int i=head[x];i;i=nex[i])
if(val[i]&&deep[to[i]]==deep[x]+1)
{
int t=dfs(to[i],min(mv-tmp,val[i]));
if(!t)deep[to[i]]=-1;
val[i]-=t;val[i^1]+=t;
tmp+=t;
if(tmp==mv)break;
}
return tmp;
}
int bfs()
{
while(!que.empty())que.pop();
memset(deep,-1,sizeof(deep));
deep[S]=0;
que.push(S);
while(!que.empty())
{
int t=que.front();
que.pop();
for(int i=head[t];i;i=nex[i])
if(val[i]&&deep[to[i]]==-1)
{
deep[to[i]]=deep[t]+1;
que.push(to[i]);
if(to[i]==T)return 1;
}
}
return 0;
}
int dinic()
{
int ret=0;
while(bfs())
ret+=dfs(S,inf);
return ret;
}
}F;
struct cactus
{
int head[N],nex[M],to[M],val[M],tot;
int vis[N],fa[N],inc[N],st[N],v[N],deep[N],top;
void add(int x,int y,int z)
{
tot++;
nex[tot]=head[x];head[x]=tot;
to[tot]=y;val[tot]=z;
}
void ade(int x,int y,int z)
{add(x,y,z);add(y,x,z);}
void dfs(int x,int y,int v1)
{
fa[x]=y;st[++top]=x;
vis[x]=1;v[x]=v1;deep[x]=deep[y]+1;
for(int i=head[x];i;i=nex[i])
if(to[i]!=y)
{
if(!vis[to[i]])
dfs(to[i],x,val[i]);
else if(deep[to[i]]<deep[x])
{
int sum=0;F.cnt++;
for(int j=top;st[j]!=to[i];j--)
{
F.ade(F.cnt,v[st[j]],1);
sum++;inc[st[j]]=1;
}
F.ade(F.S,F.cnt,sum);
F.ade(F.cnt,val[i],1);
}
}
top--;
if(!inc[x]&&fa[x])
{
F.ade(F.S,++F.cnt,1);
F.ade(F.cnt,v[x],1);
}
}
}C;
int main()
{
//freopen("tt.in","r",stdin);
scanf("%d%d",&n,&m);
F.init();
for(int i=1,x,y,z;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
C.ade(x,y,z);
}
C.dfs(1,0,0);
printf("%d\n",F.dinic());
return 0;
}