【题解】sdoj3728表格(2018-08-06集训T2)拓扑排序

25 篇文章 0 订阅
9 篇文章 0 订阅

题目链接

问题描述

给出一个表格, N 行 M 列,每个格子有一个整数,有些格子是空的。现在需要你
来做出一些调整,使得每行都是非降序的。这个调整只能是整列的移动。

输入

第一行两个正整数 N 和 M。
接下来 N 行,每行 M 个整数, -1 表示这个格子是空的,其他的整数都在 [0, 10^9]范围,表
示格子的数字。

输出

若无解,输出 -1;
否则输出任意一个解,即一行 M 个正整数 p1, p2, · · · , pm,表示可以把初始表格的 pi 列,
放在新表格的第 i 列,以得到一个合法的表格。

样例输入 1

3 3
-1 -1 -1
2 1 2
2 -1 1

样例输出 1

2 3 1

样例输入 2

2 2
1 2
2 1

样例输出 2

1

数据规模与约定

对于 20% 的数据,满足 1 ≤ N ≤ 8, 1 ≤ M ≤ 8。
对于 60% 的数据,满足 1 ≤ N × M ≤ 2 × 10^3。
对于 100% 的数据,满足 1 ≤ N × M ≤ 10^5。


题解

对每一列小到大排序,忽略-1 的。排前面的列,向后面的建边。因为有多个相同数字的,
所以建一些虚点。

2 2 3 3
在 2,3 之间建一个虚点, 2 2 向虚点建边,虚点向 3 3 建边
最后跑拓扑排序

#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#define PB(v) push_back(v)
using namespace std;
const int N=5e5+10;
int n,m;//n行m列 
struct node{
    int num,idy;//数值和初始列序号 
    bool operator <(const node&rhs)const{
    return num<rhs.num;}
}table[N];
vector<int>vx[N];//建图用
queue<int>q;//存所有入度为0的点 
int deg[N];//单行中每列的入度 
int ans[N];//记录可行解 
int main()
{
    freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);//n行m列
    int xd=m;//虚点下标 
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)//读入1行中每列的数值 
        {
            scanf("%d",&table[j].num); 
            table[j].idy=j;
        }
        sort(table,table+m);//对一行的值进行排序 
        for(int k=-1,l=0,r=0;l<m;l=r)
        {
            //k为建立的虚点,l为相同区间左端点,r为右端点
            while(r<m&&table[r].num==table[l].num)r++;
            if(table[l].num==-1)continue;
            if(k!=-1)for(int o=l;o<r;o++)vx[k].PB(table[o].idy),deg[table[o].idy]++;
            //虚点已经建立,则虚点向后连边
            k=xd++;//新建虚点
            for(int o=l;o<r;o++)vx[table[o].idy].PB(k),deg[k]++;//将之前的点向虚点连边 
        }
    }
    int top=0;
    for(int i=0;i<xd;i++)
    if(!deg[i])q.push(i);
    while(!q.empty())//拓扑排序 
    {
        int u=q.front();
        q.pop();
        if(u<m)ans[top++]=u;
        for(int i=0;i<vx[u].size();i++)
        {
            int v=vx[u][i];
            if(--deg[v]==0)q.push(v);
        }
    } 
    if(top<m)puts("-1");
    else for(int i=0;i<m;i++)printf("%d%c",ans[i]+1,i==m-1?'\n':' ');
    return 0;
}

比赛时完全没思路……对拓扑排序很不熟

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像压缩是一种通过减少图像的数据量来实现图像文件大小的减小的技术。在图像压缩中,主要使用了两种方法:有损压缩和无损压缩。 有损压缩是指压缩过程中会舍弃一些不太重要的图像细节,以减小文件大小。最常用的有损压缩算法是JPEG(Joint Photographic Experts Group)算法。JPEG算法使用了离散余弦变换(DCT)来将原始图像转换为频域中的系数,然后根据系数的重要性对其进量化和编码。这样可以达到较高的压缩比,但也会引入一定的失真。 无损压缩是指压缩过程中不会丢失任何图像信息。最常用的无损压缩算法是ZIP算法。ZIP算法使用了哈夫曼编码和LZ77算法来寻找重复的数据块并进压缩。这样可以减小文件大小,但不会改变图像的质量。 在解决图像压缩问题时,可以根据图像的特性来择适当的压缩算法和参数。如果要求高压缩比并且可以接受一定的失真,可以择JPEG算法;如果要求保持图像质量并且不要求高压缩比,可以择ZIP算法。此外,还可以使用其他的图像压缩算法,如PNG、GIF等。 总结来说,图像压缩是通过减少图像的数据量来实现图像文件大小的减小。有损压缩和无损压缩是常用的两种图像压缩方法,分别适用于不同的需求和要求。通过择合适的压缩算法和参数,可以实现理想的图像压缩效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值