• CF 274D Lovely Matrix 拓扑排序,缩点 难度:2


    http://codeforces.com/problemset/problem/274/D

    这道题解题思路:

    对每一行统计,以小值列作为弧尾,大值列作为弧头,(-1除外,不连弧),对得到的图做拓扑排序即可.

    但本题数据较大,所以需要进行缩点,把相同数值的点缩在一起,成为一个新的大点,原先的小值列向大点连接,再由大点向大值列连接,可以减少边数

    举例来说,原本取值为1的有4个点,取值为2的有5个点,

    不缩点,就需要20条边

    缩点,只需要4+1+5=10条边

    (不过我还是觉得这个方法有点投机取巧??)

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn=2e5+3;
    typedef pair<int,int> P;
    P a[maxn];
    int deg[maxn];
    bool used[maxn];
    int ans[maxn];
    vector <int >e[maxn];
    queue<int> que;
    int n,m,last,flast;
    
    int main(){
            scanf("%d%d",&n,&m);
            flast=m+1;
            for(int i=0;i<n;i++){
                    for(int j=0;j<m;j++){
                            scanf("%d",&a[j].first);
                            a[j].second=j+1;
                    }
                    sort(a,a+m);
    
                    last=flast;
                    for(int j=0;j<m;){
                            if(a[j].first==-1){j++;continue;}
                            int k=j;
                            while(a[k].first==a[j].first){
                                    e[a[k].second].push_back(last);
                                    deg[last]++;
                                    if(last>flast){
                                            e[last-1].push_back(a[k].second);
                                            deg[a[k].second]++;
                                    }
                                    k++;
                            }
                            last++;
                            j=k;
                    }
                    flast=last;
            }
            for(int i=1;i<=m;i++){
                   if(deg[i]==0){
                            que.push(i);
                   }
            }
            int len=0;
            while(!que.empty()&&len<m){
                    int s=que.front();que.pop();
                    if(used[s])continue;
                    used[s]=true;
                    if(s<=m)ans[len++]=s;
                    for(int i=0;i<e[s].size();i++){
                            int t=e[s][i];
                            if(!used[t]){
                                    deg[t]--;
                                    if(deg[t]==0){
                                            que.push(t);
                                    }
                            }
                    }
            }
            if(len<m){
                    puts("-1");
            }
            else for(int i=0;i<len;i++){
                    printf("%d%c",ans[i],i==len-1?'
    ':' ');
            }
            return 0;
    }
    

      

  • 相关阅读:
    eclipse使用egit提交代码报错
    JMeter使用代理录制脚本
    Jenkins搭建Windows slave 环境
    nmon在线安装及使用
    netstat 查看连接数
    Node.js安装及环境配置之Windows篇(转:https://www.cnblogs.com/zhouyu2017/p/6485265.html)
    HTTP状态码图示
    高并发带来的重复提交问题解决方案
    redis 主从备份自动切换+java代码实现类
    转:Redis 缓存策略
  • 原文地址:https://www.cnblogs.com/xuesu/p/4328706.html
Copyright © 2020-2023  润新知