zoukankan      html  css  js  c++  java
  • ARC097D Equals

    传送门

    题目

    We have a permutation of the integers from 1 through N, p1, p2, .., pN. We also have M pairs of two integers between 1 and N (inclusive), represented as (x1,y1), (x2,y2), .., (xM,yM). AtCoDeer the deer is going to perform the following operation on p as many times as desired so that the number of i (1 i N) such that pi=i is maximized:

    Choose j such that 1 j M, and swap pxj and pyj.

    Find the maximum possible number of i such that pi=i after operations.

    Constraints

    • 2 N 105
    • 1 M 105
    • p is a permutation of integers from 1 through N.
    • 1 xj,yj N
    • xj yj
    • If i j, {xi,yi} {xj,yj}.
    • All values in input are integers

    Input

    Input is given from Standard Input in the following format:

    N M
    p1 p2 .. pN
    x1 y1
    x2 y2
    :
    xM yM
    

    Output

    Print the maximum possible number of i such that pi=i after operations.

    题目大意

    给了一个数组,一堆pair,可随意交换任意次pair对应的下标的数,求数组里面下标等于元素值的最多对数。

    分析

    将初始位置的下标和元素值连边,然后将能互相交换的下标连边,然后Tarjan缩点,判断下标和元素值是否在同一联通分量中即可,注意让代表下标的点与代表元素值的点错开即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define pb push_back
    int d[110000];
    int belong[210000],cnt,sum,dfn[210000],low[210000],ist[210000];
    vector<int>v[200010];
    stack<int>a;
    void tarjan(int x){
        int i,j,k;
        dfn[x]=low[x]=++cnt;
        a.push(x);
        ist[x]=1;
        for(i=0;i<v[x].size();i++)
            if(!dfn[v[x][i]]){
                tarjan(v[x][i]);
                low[x]=min(low[x],low[v[x][i]]);
            }else if(ist[v[x][i]]){
                low[x]=min(low[x],dfn[v[x][i]]);
            }
            if(low[x]==dfn[x]){
                 sum++;
                 while(1){
                     int u=a.top();
                     a.pop();
                     ist[u]=0;
                     belong[u]=sum;
                     if(u==x)break;
                 }
            }
    }
    int main()
    {   int n,m,i,j,k,x,y;
        cin>>n>>m;
        for(i=1;i<=n;i++){
            cin>>d[i];
            v[i].pb(d[i]+n);
            v[d[i]+n].pb(i);
        }
        for(i=1;i<=m;i++){
            cin>>x>>y;
            v[x].pb(y);
            v[y].pb(x);
        }
        for(i=1;i<=2*n;i++)
            if(!dfn[i])tarjan(i);
        int ans=0;
            for(i=1;i<=n;i++){
                if(belong[i]==belong[i+n])ans++;
            }
        cout<<ans<<endl;
        return 0;
    }

  • 相关阅读:
    脚本绘图工具总结
    Windows Server 2012 磁盘管理之 简单卷、跨区卷、带区卷、镜像卷和RAID-5卷
    Java web项目 本地配置https调试
    Twitter的分布式自增ID算法snowflake (Java版)
    Redis压测命令
    Java读取txt文件信息并操作。
    安装配置adb工具及遇到的问题
    数据库逆向生成数据库表详细设计文档
    Java常用日期处理方法
    Date与String互相转换及日期的大小比较
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9088600.html
Copyright © 2011-2022 走看看