码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-03-11 00:24:51      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

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?‘\n‘:‘ ‘);
        }
        return 0;
}

  

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

标签:

原文地址:http://www.cnblogs.com/xuesu/p/4328706.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!