[SCOI2010]连续攻击游戏
本场考试洛谷难度评级最弱的一道,然而考场上只是敲了个暴力,就特别离谱。总结下来应该是我练题不够,毕竟二分图到现在为止还是只敲过模板,于是遇到稍微有点变通的题目就不会做了,这一点以后一定要弥补回来。
说回题目本身。这道题有一个限制,即每个武器只能被使用一次,而又因为每个武力值也只会使用一次,这就构成了一个一一对应的关系,于是乎题目要求就变成了一个求最大匹配数的问题。又由于显然武器集合与武力值集合并无交集,便可以抽象成二分图后用最大匹配来求解。然后就是要注意由于需要连续的一些数,我们应该从小到大依次枚举武力值,如果一个点时无法增广,退出循环即可,这是唯一与模板不同的地方。复杂度鬼知道,能过就行。
#include<cstdio>
//#define zczc
const int N=1000010;
const int M=1010;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w>='0'&&w<='9'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m,a,b;
struct edge{
int t,next;
}e[N<<1];
int esum,head[N<<1];
inline void add(int fr,int to){
e[++esum]=(edge){to,head[fr]};head[fr]=esum;
}
int c[N<<1],vis[N<<1],nt;
inline bool dfs(int wh){
for(int i=head[wh],th;i;i=e[i].next){
if(vis[th=e[i].t]==nt)continue;vis[th]=nt;
//printf("now:%d %d %d\n",wh,th-N,c[th]);
if(c[th]==0||dfs(c[th]))return c[th]=wh,true;
}
return false;
}
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
read(m);
for(int i=1;i<=m;i++){
read(a);read(b);
add(a,N+i);add(b,N+i);
}
int ans=0;
for(int i=1;;i++){
//printf("ans:%d %d\n",i,ans);
++nt;
if(dfs(i))ans++;
else break;
}
printf("%d\n",ans);
return 0;
}
一如既往,万事胜意

浙公网安备 33010602011771号