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

  

时间: 2024-10-13 21:29:42

CF 274D Lovely Matrix 拓扑排序,缩点 难度:2的相关文章

CF Fox And Names (拓扑排序)

Fox And Names time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Fox Ciel is going to publish a paper on FOCS (Foxes Operated Computer Systems, pronounce: "Fox"). She heard a rumor: the

CF 1033C Permutation Game 拓扑+排序

题意:一个全排列,alice可以从某一个数出发,从i走到j的条件是: a[j]>a[i],而且从i到j要符合|i-j|%a[i]=0,若alice在该数有必胜的策略,输出B,否则A 思路,拓扑排序+博弈论(这题让我做的太迷了刚刚) ,用邻接表连接该数与其他数的关联,如果一开始入度为0的,即alice选择该点后,对方无法走去另一个点,alice会赢,把它们坐标存进一个数组里,再把它们连边进行分析,就可以判断出谁输谁赢,详情可看代码. #include <iostream> #include

【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 318[Submit][Status][Discuss] Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti.Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意

HDU1811 Rank of Tetris 【缩点】+【拓扑排序】

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5447    Accepted Submission(s): 1526 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

【差分约束系统】【强连通分量缩点】【拓扑排序】【DAG最短路】CDOJ1638 红藕香残玉簟秋,轻解罗裳,独上兰舟。

题意: 给定n个点(点权未知)和m条信息:u的权值>=v的权值+w 求点权的极小解和极大解(无解则输出-1) 极小解即每个点的点权可能的最小值 极大解即每个点的点权可能的最大值 题解: 差分约束系统 对于val[u]>=val[v]+w 要得到极小解,v是没有受限制的,其最小值为0 而u受到v的限制,显然,val[u]的最小值就是val[v]+w 在多条件限制下,我们用v连向u边权为w的边表示每个限制条件val[u]>=val[v]+w 那么如果得到的是拓扑图,则按拓扑序求到每个点的最长

POJ 3114 - Countries in War(强连通分量+缩点+拓扑排序+DAG最短路)

Countries in War Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Appoint description: Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The impor

POJ 2762判断单联通(强连通缩点+拓扑排序)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14789   Accepted: 3915 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

hihoCoder#1185 : 连通性&#183;三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值

题目链接: http://hihocoder.com/problemset/problem/1185# 题意: n个点,每个点有一个权值,m条有向边,从1出发,每走到一个点, 就吃掉这个点的草,当没有可以到达的草场或是能够到达的草场都已经被吃光了之后就要返回到1了.求最多可以吃掉多少草. 思路: 提示里面讲的挺好的 如果草场是一个强连通图,那么我们只要走到任意一点,就可以把其他所有的草场都走一遍,并且可以选择任意一个点作为终点.所以把强联通块缩成一个点 因为一个强连通块会被缩成一个点,那么我们可

POJ 2762推断单个联通(支撑点甚至通缩+拓扑排序)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14789   Accepted: 3915 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors