• BestCoder Round #74


    身败名裂啊。。。。。。

    T1WA了半天,30min才A。

    T2又WA了一发,然后Hack刚2min就被别人叉了。

    T3做完后最后40min不知所措。

    去叉别人,看到一个人写D题判m=0很奇怪,随手把他叉了:

    1

    3 0

    然后发现,标程输出1.

    奥妙重重

    嘿嘿嘿,我竟然又去叉了吉利。

    T1的SB错误是,答案可能是|x-y|。

    T2的SB错误是,一个[1,10^5]的数异或[1,10^5]的数可能是[1,131072]的数。

    T1 Shortest Path

    x到y的路径可能有几种:
    1.x->y

    2.x->i->j>y

    其中i和j是新边里的节点(称为关键节点)

    将六个关键点连起来跑一下Floyd,然后每次询问时枚举一下i,j。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<map>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=100010;
    int n,m,u[5],v[5],A[10],cnt;
    int W[10][10];
    map<int,int> M;
    int find(int x) {
        if(!M.count(x)) M[x]=++cnt,A[cnt]=x;
        return M[x];
    }
    const int mod=1000000007;
    int main() {
        dwn(T,read(),1) {
            n=read();m=read();M.clear();cnt=0;
            rep(i,1,6) rep(j,1,6) W[i][j]=100000000;
            rep(i,1,6) W[i][i]=0;
            rep(i,1,3) u[i]=read(),v[i]=read(),W[find(u[i])][find(v[i])]=W[find(v[i])][find(u[i])]=1;
            rep(i,1,cnt) rep(j,1,cnt) W[i][j]=min(W[i][j],abs(A[i]-A[j]));
            rep(k,1,cnt) rep(i,1,cnt) rep(j,1,cnt) W[i][j]=min(W[i][j],W[i][k]+W[k][j]);
            long long res=0;
            rep(i,1,m) {
                int x=read(),y=read(),ans=abs(x-y);
                rep(k,1,cnt) rep(j,1,cnt) ans=min(ans,abs(A[k]-x)+abs(A[j]-y)+W[k][j]);
                (res+=(long long)i*ans)%=mod;
            }
            printf("%I64d
    ",res);
        }
        return 0;
    }
    View Code

    T2 Transform

    x -> y  <=> 0 -> x xor y

    所以从0BFS一下就好了。

    然后应该搜到[1,131072]。QAQ(AQ)*

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=300010;
    const int mod=1000000007;
    typedef long long ll;
    int n,m,A[maxn],vis[maxn],d[maxn];
    queue<int> Q;
    void bfs() {
        memset(vis,0,sizeof(vis));d[0]=0;vis[0]=1;Q.push(0);
        while(!Q.empty()) {
            int x=Q.front();Q.pop();
            rep(i,0,20) {
                int v=x^(1<<i);
                if(v<=300000&&!vis[v]) {
                    vis[v]=1;d[v]=d[x]+1;Q.push(v);
                }
            }
            rep(i,1,n) {
                int v=x^A[i];
                if(v<=300000&&!vis[v]) {
                    vis[v]=1;d[v]=d[x]+1;Q.push(v);
                }
            }
        }
    }
    int main() {
        dwn(T,read(),1) {
            n=read();m=read();
            rep(i,1,n) A[i]=read();
            bfs();ll ans=0;
            rep(i,1,m) (ans+=(ll)i*d[read()^read()])%=mod;
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code

    T3 Toposort

    我们逐位考虑,那么我们需要一个数据结构完成这样的功能。

    1.找到当前权值<=k的最小节点。

    2.将一个节点的权值-1。

    显然线段树就行了。

    我懒得写线段树,于是STL大法好。

    用一个堆来维护一下在某次操作前权值<=k的节点,不行就把它踢出去。

    然后拓扑的时候再判判能不能扔到堆里。

    因为最多有n+m个节点进入堆,所以时间复杂度为O((n+m)logn)。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<queue>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int mod=1000000007;
    const int maxn=100010;
    const int maxm=200010;
    typedef long long ll;
    int n,m,k,first[maxn],Next[maxm],to[maxm],in[maxn],is[maxn],e;
    void AddEdge(int u,int v) {
        to[++e]=v;Next[e]=first[u];first[u]=e;in[v]++;
    }
    int main() {
        dwn(T,read(),1) {
            n=read();m=read();k=read();
            rep(i,1,n) in[i]=first[i]=is[i]=0;e=0;
            rep(i,1,m) {
                int u=read(),v=read();
                AddEdge(u,v);
            }
            priority_queue<int> Q;
            rep(i,1,n) if(in[i]<=k) is[i]=1,Q.push(-i);
            ll ans=0;
            rep(j,1,n) {
                int x;
                while(Q.size()) {
                    x=-Q.top();Q.pop();is[x]=0;
                    if(in[x]<=k) break;
                }
                (ans+=(ll)j*x)%=mod;k-=in[x];in[x]=0;is[x]=1;
                for(int i=first[x];i;i=Next[i]) if(in[to[i]]) {
                    in[to[i]]--;
                    if(in[to[i]]<=k&&!is[to[i]]) is[to[i]]=1,Q.push(-to[i]);
                }
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code

    T4 Deletion

    比赛时并没有想出来QAQ(AQ)*

    这道题想法很妙,考虑题目说的“要求选出来的边构成的子图的每个连通块最多只有一个环”其实就是环套树。

    而如果对一个无向图进行定向,满足所有节点的出边最多只有1,那么这个无向图可以一次选出。

    所以问题转化成对一个无向图进行定向,让出边最多的节点出度最少,那么二分答案后就是一个分配模型了。

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i!=-1;i=Next[i])
    using namespace std;
    typedef long long ll;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=5010;
    const int maxm=100010;
    const int inf=1e9;
    struct Dinic {
        int n,m,s,t,first[maxn],Next[maxm];
        void init(int n) {
            m=0;this->n=n;
            memset(first,-1,sizeof(first));
        }
        struct Edge {int from,to,flow;}edges[maxm];
        void AddEdge(int u,int v,int w) {
            edges[m]=(Edge){u,v,w};Next[m]=first[u];first[u]=m++;
            edges[m]=(Edge){v,u,0};Next[m]=first[v];first[v]=m++;
        }
        int d[maxn],vis[maxn],cur[maxn];
        int BFS() {
            memset(vis,0,sizeof(vis));
            queue<int> Q;Q.push(s);vis[s]=1;
            while(!Q.empty()) {
                int x=Q.front();Q.pop();cur[x]=first[x];
                ren {
                    Edge& e=edges[i];
                    if(!vis[e.to]&&e.flow) {
                        vis[e.to]=1;
                        d[e.to]=d[x]+1;
                        Q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
        int DFS(int x,int a) {
            if(x==t||!a) return a;
            int flow=0,f;
            for(int& i=cur[x];i!=-1;i=Next[i]) {
                Edge& e=edges[i];
                if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.flow)))) {
                    e.flow-=f;edges[i^1].flow+=f;
                    a-=f;flow+=f;if(!a) break;
                }
            }
            return flow;
        }
        int solve(int s,int t) {
            this->s=s;this->t=t;int flow=0;
            while(BFS()) flow+=DFS(s,inf);
            return flow;
        }
    }sol;
    int n,m,u[maxn],v[maxn];
    int check(int x) {
        int s=n+m+1,t=n+m+2;sol.init(t);
        rep(i,1,n) sol.AddEdge(s,i,x);
        rep(i,1,m) sol.AddEdge(i+n,t,1);
        rep(i,1,m) sol.AddEdge(u[i],i+n,1),sol.AddEdge(v[i],i+n,1);
        return sol.solve(s,t)==m;
    }
    void solve() {
        n=read();m=read();
        rep(i,1,m) u[i]=read(),v[i]=read();
        if(!m) {puts("0");return;}
        int l=1,r=m,mid;
        while(l<r) if(check(mid=l+r>>1)) r=mid; else l=mid+1;
        printf("%d
    ",l);
    }
    int main() {
        dwn(T,read(),1) solve();
        return 0;
    }
    View Code
  • 相关阅读:
    cocos2dx ListView 动态加载(代码)
    cocos2dx ListView 大量 Item 加载方案(转)
    ListView 两列多行实现
    C++Study 指针详解
    cocos2d-x3.2 studio -------- 打包apk
    Quick-cocos2d-x3.3 Study (二十一)--------- 随机数
    Cocos2d-x 3.x使用第三方库播放gif图
    Cocos Studio ---------- 使用 C++ 开发游戏( 选门 )
    Quick-cocos2d-x3.3 Study (二十)--------- 音乐音效
    javaBean
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5248571.html
Copyright © 2020-2023  润新知