• 【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;
    }  
  • 相关阅读:
    mysql报错:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
    MD5登陆密码的生成
    15. 3Sum、16. 3Sum Closest和18. 4Sum
    11. Container With Most Water
    8. String to Integer (atoi)
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    几种非线性激活函数介绍
    AI初探1
    AI初探
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11626866.html
Copyright © 2020-2023  润新知