zoukankan      html  css  js  c++  java
  • 【10.5】

    1>团伙

    虚点+并查集

    将i+n当做桥梁,作为敌人敌人关系转化的桥梁

    朋友的朋友是朋友,朋友的敌人是敌人

    敌人的敌人是朋友,敌人的朋友是敌人

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    using namespace std;
    int n,m;char c;
    const int N=1003;
    int fa[N<<1];
    bool vis[N<<1];
    int find(int x)
    { return !fa[x] ?x :fa[x]=find(fa[x]); }
    void merge(int u,int v)
    {
        u=find(u),v=find(v);
        if(u!=v) fa[u]=v;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        int u,v;
        for(int i=1;i<=m;i++)
        {
            cin>>c;
            scanf("%d%d",&u,&v);
            
            if(c=='F')
                merge(u,v),merge(u+n,v+n);//加后面那句就错,但是我想加  
            else 
                merge(v+n,u),merge(u+n,v);
        }
        
        int ans=0;
        for(int i=1;i<=n;i++)//有点悬的写法,要求上面合并的顺序是>n -> <n! 
            if(!fa[i]) ans++;
        printf("%d
    ",ans);
        return 0;
    }

    2>关押罪犯

    虚点+并查集

    思路同上

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    int n,m;
    const int N=20003,M=100003;
    int fa[N<<1];
    int find(int x)
    { return !fa[x] ?x :fa[x]=find(fa[x]); }
    void merge(int u,int v)
    {
        u=find(u),v=find(v);
        if(u!=v) fa[u]=v;
    }
    
    struct node
    {
        int u,v,w;
        bool operator < (const node & o) const
        { return w>o.w; }
    } g[M];
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&g[i].u ,&g[i].v ,&g[i].w );
        sort(g+1,g+m+1);
        
        for(int i=1;i<=m;i++)
        {
            int fu=find(g[i].u ),fv=find(g[i].v );
            if(fu==fv)
            {
                printf("%d
    ",g[i].w );
                return 0;
            } 
            else 
                merge(fu,g[i].v +n),merge(fv,g[i].u +n);
        } 
        printf("0
    ");
        return 0;
    }

    方法二:二分算法

    思路来自题目中的单调性,

    check就是由二分图的染色判断写出来的

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    int n,m;
    const int N=20003,M=100003;
    struct node
    {
        int u,v,w;
        bool operator < (const node & o) const
        { return w<o.w; }
    } g[M];
    struct nd
    {
        int v,w;
        nd(int vv,int ww)
        {v=vv,w=ww;} 
        nd(){}
    };
    vector <nd> sd[N];
    
    int st[N];
    bool check(int mid)
    {
        memset(st,0,sizeof(st));
        int mx=g[mid].w ;
        queue <int> q;    
        for(int i=1;i<=n;i++)
            if(!st[i])
            {
                st[i]=1;
                q.push(i);
                while(!q.empty())
                {
                    int t=q.front();q.pop();
                    int sz=sd[t].size();
                    for(int j=0;j<sz;j++)
                    {
                        if(sd[t][j].w<=mx || st[sd[t][j].v]+st[t]==3) continue;
                        if(st[sd[t][j].v] ==st[t]) return false;
                        st[sd[t][j].v]=3-st[t];
                        q.push(sd[t][j].v ) ;
                    }
                }
            }
        return true;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&g[i].u ,&g[i].v ,&g[i].w );
            sd[g[i].u ].push_back(nd(g[i].v ,g[i].w ));
            sd[g[i].v ].push_back(nd(g[i].u ,g[i].w ));
        }
        sort(g+1,g+m+1);
        
        int l=0,r=m+1;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid)) r=mid-1 ;
            else l=mid+1;
        }
        printf("%d
    ",g[l].w );
        return 0;
    }

    3>填涂颜色

    bfs染色 to分区域

    转化思路:
    找一块'0',使其没有位于边界位置的'0'
    所以dfs找联通块,然后判断

    #include<cstdio>
    #include<cstdlib>
    #include<queue>
    using namespace std;
    int n;
    const int N=33;
    int mp[N][N];
    
    int py[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    int cnt,nm[N][N];
    bool bj[N*N];
    queue <int> q;
    void bfs(int x,int y,int xh)
    {
        while(!q.empty()) q.pop();
        q.push(x),q.push(y);
        nm[x][y]=xh; 
        
        while(!q.empty())
        {
            int ix=q.front();q.pop();
            int iy=q.front();q.pop();
            
            for(int i=0;i<4;i++)
            {
                int nx=ix+py[i][0];
                int ny=iy+py[i][1];
                
                if(!nx || !ny || nx>n || ny>n ) continue;
                if(nm[nx][ny] || mp[nx][ny]==1 ) continue; 
                nm[nx][ny]=xh;//bfs一定要先标记,再入队!!!!!!!!! 
                q.push(nx),q.push(ny);
            }
        }
        
    }

    4>

    bfs染色 搜索

    拯救oibh总部

    C++获取字符cin,getchar,get,getline的区别

    cin>>(char) 与 getchar()

    cin会过滤掉不可见字符(空格,换行,回车)

    #include<cstdio>
    #include<cstdlib>
    #include<queue>
    #include<iostream>
    using namespace std;
    int n,m;char c;
    const int N=503;
    int mp[N][N];
    
    int py[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
    void bfs(int x,int y)
    {
        queue <int> q;
        q.push(x),q.push(y);
        mp[x][y]=1;
        
        while(!q.empty())
        {
            int ix=q.front();q.pop();
            int iy=q.front();q.pop();
            
            for(int i=0;i<4;i++)
            {
                int nx=ix+py[i][0];
                int ny=iy+py[i][1];
                
                if(!nx || !ny || nx>n || ny>m ) continue;
                if(mp[nx][ny]) continue;
                mp[nx][ny]=1;
                q.push(nx),q.push(ny);
            }       
        }
    }
    
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                cin>>c;
                if(c=='*') mp[i][j]=1;
            }
        
        for(int i=1;i<=n;i++)
        {
            if(!mp[i][1]) bfs(i,1);
            if(!mp[i][m]) bfs(i,m);
        }
        for(int i=1;i<=m;i++)
        {
            if(!mp[1][i]) bfs(1,i);
            if(!mp[n][i]) bfs(n,i);
        }
        
        int ans=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(!mp[i][j]) ans++;
        cout<<ans;
        return 0;
    }  
  • 相关阅读:
    VIVADO固化
    Keil MDK 编译器 AC5 和 AC6 优化选项重要内容和区别
    STM32时钟
    STlink/v2中SWD模式连线方式
    搭载M33内核,支持最新蓝牙5.1,晚到的DA1469x生正逢时
    超全国内外蓝牙芯片原厂总结(含芯片型号)
    芯片封装类型大全
    国务院办公厅关于2012年部分节假日安排的通知
    美国摇滚乐队Metro致敬黄家驹,全粤语翻唱Beyond经典《海阔天空》
    国务院办公厅发布2010年部分节假日安排通知
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11626866.html
Copyright © 2011-2022 走看看