I Interesting Computer Game 2020牛客暑期多校训练营(第八场)

https://ac.nowcoder.com/acm/contest/5673/I

上周才做了一道二分图匹配用dinic跑复杂度是msqrt(n)的题,这里t=10过不了3n个点2n条边过不了,T了好久最后写了个贪心,但不会证明正确性。。。

对于每个数字,统计他在多少个位置出过,然后找到他与哪些数字在同一个位置过

我们每次找出当前出线次数最小的数字u,然后扫一遍他冲突的数字,其中没有被选取的中剩余出线最多的v,就选那个u和v冲突的位置,让sum[v]--,这样一直做下去直到没有数字可选。用set维护找出最少的数字

#include
namespace FastIO {
    const int SIZE = 1 << 16;
    char buf[SIZE], obuf[SIZE], str[60];
    int bi = SIZE, bn = SIZE, opt;
    int read(char *s) {
        while (bn) {
            for (; bi < bn && buf[bi] <= ' '; bi++);
            if (bi < bn) break;
            bn = fread(buf, 1, SIZE, stdin);
            bi = 0;
        }
        int sn = 0;
        while (bn) {
            for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
            if (bi < bn) break;
            bn = fread(buf, 1, SIZE, stdin);
            bi = 0;
        }
        s[sn] = 0;
        return sn;
    }
    bool rd(int& x) {
        int n = read(str), bf;
        if (!n) return 0;
        int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
        for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
        if (bf < 0) x = -x;
        return 1;
    }
};
using namespace FastIO;
using namespace std;

const int maxl=3e5+10;
const int inf=2e9;

int S,T,n,tot,cas,cnt,ans;
int a[maxl],b[maxl],c[maxl],sum[maxl];
typedef pair p;
set

s; vectore[maxl]; bool in[maxl]; inline int id(int x) { return lower_bound(c+1,c+1+tot,x)-c; } inline void prework() { //scanf("%d",&n); rd(n); tot=0;int aa,bb; for(register int i=1;i<=n;++i) { //scanf("%d%d",&a[i],&b[i]); rd(a[i]);rd(b[i]); c[++tot]=a[i];c[++tot]=b[i]; } sort(c+1,c+1+tot); tot=unique(c+1,c+1+tot)-c-1; for(int i=1;i<=tot;++i) sum[i]=0,e[i].clear(); for(int i=1;i<=n;++i) if(a[i]==b[i]) ++sum[id(a[i])]; else { aa=id(a[i]);bb=id(b[i]); ++sum[aa],++sum[bb]; e[aa].push_back(bb); e[bb].push_back(aa); } s.clear(); for(int i=1;i<=tot;i++) s.insert({sum[i],i}),in[i]=true; } inline void mainwork() { int u,v,id,mx;ans=0;p d; while(s.begin()!=s.end()) { d=(*s.begin()); if(d.first==0) break; u=d.second;in[u]=false;++ans; s.erase(s.begin()); mx=0,id=0; for(int v:e[u]) if(in[v] && sum[v]>mx) id=v,mx=sum[v]; if(id!=0) { s.erase(s.lower_bound({sum[id],id})); --sum[id]; if(sum[id]==0) in[id]=false; else s.insert({sum[id],id}); } } } inline void print() { printf("Case #%d: %d\n",cas,ans); } int main() { int t; //scanf("%d",&t); rd(t); for(cas=1;cas<=t;cas++) { prework(); mainwork(); print(); } return 0; }

 

你可能感兴趣的:(I Interesting Computer Game 2020牛客暑期多校训练营(第八场))