洛谷 P1640 [SCOI2010]连续攻击问题

洛谷

一句话题意:

每个武器有两种属性,每种武器只能选择一种属性,从属性1连续递增才算攻击,求最大连续攻击次数。

因为同学告诉我这是二分图最大匹配,自然就往那个方向去想。

那么怎么建图呢?

每个武器只能用一次,所以武器占二分图的一边,另一边放属性。

每个武器对应的属性之间连边。

因为要从属性1开始连续递增,所以用属性那一边匹配武器,for循环寻找武器,找到了就ans++,若没找到就输出ans,return 0;

这里要说一个细节,那个同学的标记数组vis是int类型,所以memset的时候会非常慢。所以可以考虑改成bool类型。

code:

#include <bits/stdc++.h>
using namespace std;

const int N=1000010;
bool vis[N];
int n,ans;
int s[N<<1][2],o[N],pos[N];

void add(int x,int y)
{
    s[++o[0]][1]=o[x],s[o[0]][0]=y,o[x]=o[0];
}

bool find(int x)
{
    if (vis[x]) return 0;
    vis[x]=1;
    for (int i=o[x];i;i=s[i][1]) {
        int y=s[i][0];
        if (!pos[y]||find(pos[y])) {
            pos[y]=x;
            return 1;
        }
    }
    return 0;
}

int main()
{
    int a1,a2;
    cin>>n;
    for (int i=1;i<=n;++i) {
        scanf("%d%d",&a1,&a2);
        add(a1,i),add(a2,i);
    }
    for (int i=1;i<=n;++i) {
        if (find(i)) ++ans;
        else break;
        memset(vis,0,sizeof(vis));
    }
    cout<<ans;
    return 0;
}
posted @ 2018-08-24 08:16  fuyan0101  阅读(114)  评论(0编辑  收藏  举报