zoukankan      html  css  js  c++  java
  • [洛谷P1330]封锁阳光大学

    题目大意:有n个点和m条路(双向),要你在某些点上放“河蟹”来“占领”这个点的所有路,但是任意两只河蟹不能放在有路径连接的两个点上,否则会打架,求最少多少只河蟹使得所有路全被占领,或者不可能全部占领。

    算法:BFS(或DFS)染色

    思路:因为BFS有分层效果,于是我使用BFS将每个联通块染成黑色和白色。如果两个相同颜色的点有路,说明不能放置河蟹,输出“Impossible”。否则对于每个联通块,算出黑、白各有几个点,取两者较小数加到答案中。所有联通块的点数之和即为答案。

    此题数据规模较大,BFS时数组要开小点(内存越小速度似乎越快使用std::queue的请忽略),我丧心病狂地加了读优,加了inline,改了又改,最后数组减小改为循环队列,就过了……

     

    没错就是这个点!!!

    C++ Code:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #define C c=getchar()
    using namespace std;
    int n,m,cnt=0,ans=0,head[200050],next[200050],dist[200050],colour[10005],q[100005],st[100005];
    inline int readint(){
        int C;
        while(!isdigit(c))C;
        int p=0;
        while(isdigit(c)){
            p=p*10+c-'0';
            C;
        }
        return p;
    }
    inline void ins(int x,int y){
        cnt++;
        next[cnt]=head[x];
        head[x]=cnt;
        dist[cnt]=y;
        cnt++;
        next[cnt]=head[y];
        head[y]=cnt;
        dist[cnt]=x;
    }
    void bfs(int begin){
        memset(q,0,sizeof q);
        memset(st,0,sizeof st);
        int l=0,r=1;
        q[1]=begin;
        st[1]=1;
        int f[2]={0,1};
        colour[begin]=1;
        while(l!=r){
            l=(l+1)%100000;
            int now=q[l];
            for(int i=head[now];i;i=next[i]){
                int t=dist[i];
                if(colour[t]==-1){
                    colour[t]=(1+st[l])%2;
                    r=(r+1)%100000;
                    q[r]=t;
                    st[r]=st[l]+1;
                    f[colour[t]]++;
                }else
                if(colour[t]==colour[now]){
                    puts("Impossible");
                    exit(0);
                }
            }
        }
        ans+=(f[0]<f[1])?(f[0]):(f[1]);
    }
    int main(){
        memset(next,0,sizeof next);
        memset(colour,0xff,sizeof(colour));
        memset(dist,0,sizeof dist);
        n=readint(),m=readint();
        for(int i=1;i<=m;i++){
            int x,y;
            x=readint(),y=readint();
            ins(x,y);
        }
        for(int i=1;i<=n;i++)
        if(colour[i]==-1)bfs(i);
        printf("%d
    ",ans);
        return 0;
    }
    

     ----------------------------------------------------------2017.7.10----------------------------------------------------------

    补充dfs的代码,思路与bfs一样,dfs是每搜一个换一种颜色。

    重点在于,你看dfs的耗时与上面bfs的差距!!!

    这差距也太大了吧!!

    C++ Code:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #define C c=getchar()
    using namespace std;
    int n,m,cnt=0,ans=0,head[200050],next[200050],dist[200050],colour[10005];
    int f[2];
    inline int readint(){
        int C;
        while(!isdigit(c))C;
        int p=0;
        while(isdigit(c)){
            p=p*10+c-'0';
            C;
        }
        return p;
    }
    inline void ins(int x,int y){
        cnt++;
        next[cnt]=head[x];
        head[x]=cnt;
        dist[cnt]=y;
        cnt++;
        next[cnt]=head[y];
        head[y]=cnt;
        dist[cnt]=x;
    }
    void dfs(int begin,int co){
    	colour[begin]=co;
    	f[co]++;
    	for(int i=head[begin];i;i=next[i]){
    		if(colour[dist[i]]==-1)
    		dfs(dist[i],1-co);
    		else
    		if(colour[dist[i]]==co){
    			printf("Impossible
    ");
    			exit(0);
    		}
    	}
    }
    int main(){
        memset(next,0,sizeof next);
        memset(colour,0xff,sizeof(colour));
        memset(dist,0,sizeof dist);
        n=readint(),m=readint();
        for(int i=1;i<=m;i++){
            int x,y;
            x=readint(),y=readint();
            ins(x,y);
        }
        for(int i=1;i<=n;i++)
        if(colour[i]==-1){
        	f[0]=f[1]=0;
    		dfs(i,0);
    		ans+=f[0]<f[1]?f[0]:f[1];
    	}
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Oracle 性能优化之一二
    要一直知道什么是最重要的
    c# 当引用类型作为方法的参数
    BI测试工具之跨数据库数据对比,支持oracle,sqlserver
    c#分页读取GB文本文件
    Merge compare columns when null
    Oracle常用plsql
    quick sort java version
    基于元数据的ETL系统
    Centos 6.5(64bit)上安装Vertica single node
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/6986313.html
Copyright © 2011-2022 走看看