zoukankan      html  css  js  c++  java
  • [HNOI2019]校园旅行(建图优化+bfs)

    30分的O(m^2)做法应该比较容易想到:令f[i][j]表示i->j是否有解,然后把每个路径点数不超过2的有解状态(u,v)加入队列,然后弹出队列时,两点分别向两边搜索边,发现颜色一样时,再修改答案,加入队列即可。

    100分是挺难想的,是个思维题,可以把边分成连接同色和异色两种。发现走过的路径一定是若干同色连通块拼接而成,除了中间的连通块外,其余长度均相等。对于长度,如果短,可以反复走把长度走到相等,重点是奇偶性要相同。所以,我们能够联想和二分图有关的东西。异色连通块,很显然是二分图,于是我们可以直接建立生成树。而同色的,如果是二分图则无需改变奇偶性,也连成一棵树。反之,则在树上连个自环即可,这样可以改变奇偶性。复杂度O(n^2)。据说HNOI今年卡栈,写dfs的都爆零?算了AH已经不和HN联考也不管了,反正OJ上过了……

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int>pii;
    const int N=5005,M=1e6+7;
    int n,m,Q,cnt,fa[N],hd[N],v[M],nxt[M],col[N];
    char str[N];
    bool f[N][N];
    vector<int>G[N];
    queue<pii>q;
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void add(int x,int y){v[++cnt]=y,nxt[cnt]=hd[x],hd[x]=cnt;}
    bool dfs(int u,int c)
    {
        col[u]=c;
        bool ret=0;
        for(int i=0;i<G[u].size();i++)
        if(col[G[u][i]]==-1)
        {
            add(u,G[u][i]),add(G[u][i],u);
            ret|=dfs(G[u][i],c^1);
            f[u][G[u][i]]=f[G[u][i]][u]=1;
            q.push(pii(min(u,G[u][i]),max(u,G[u][i])));
        }
        else if(col[G[u][i]]==c)ret=1;
        return ret;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&Q);
        scanf("%s",str+1);
        for(int i=1;i<=n;i++)fa[i]=i;
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            if(str[x]==str[y])G[x].push_back(y),G[y].push_back(x);
            else{
                int u=find(x),v=find(y);
                if(u!=v)fa[u]=v,add(x,y),add(y,x);
            }
        }
        memset(col,-1,sizeof col);
        for(int i=1;i<=n;i++)if(col[i]==-1&&dfs(i,0))add(i,i);
        for(int i=1;i<=n;i++)f[i][i]=1,q.push(pii(i,i));
        while(!q.empty())
        {
            int x=q.front().first,y=q.front().second;
            q.pop();
            for(int i=hd[x];i;i=nxt[i])
            for(int j=hd[y];j;j=nxt[j])
            if(str[v[i]]==str[v[j]]&&!f[v[i]][v[j]])
            f[v[i]][v[j]]=f[v[j]][v[i]]=1,q.push(pii(min(v[i],v[j]),max(v[i],v[j])));
        }
        while(Q--)
        {
            int x,y;scanf("%d%d",&x,&y);
            if(f[x][y])puts("YES");else puts("NO");
        }
    }
    View Code
  • 相关阅读:
    Oracle架构实现原理、含五大进程解析(图文详解)
    Oracle架构实现原理、含五大进程解析(图文详解)
    mysqldump --flush-logs
    mysql dump 参数
    Windows 8.1 PLSQL_32连接到RHEL6.1 Oracle10gr2_64
    Windows 8.1 PLSQL_32连接到RHEL6.1 Oracle10gr2_64
    echarts-单柱状图
    echarts-all.js:1 Dom’s width & height should be ready before init.
    如果是在有master上开启了该参数,记得在slave端也要开启这个参数(salve需要stop后再重新start),否则在master上创建函数会导致replaction中断。
    mysql 创建函数 error Code: 1227. Access denied;
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10800719.html
Copyright © 2011-2022 走看看