hdu 5092 Seam Carving

  这道题 我没看出来 他只可以往下走,我看到的 8-connected ;所以今天写一下如果是 8-connected 怎么解;

其实说白了这个就是从上到下走一条线到达最后一行的距离最小; 从Map【a】【b】 到Map【a】【b+1】 的距离是Map【a】【b+1】 以此类推:建图即可;

然后在加一个点0,和n+m+1 点这样在建立一下从  0 点到第一行的边,和最后一行到(n+m+1) 的边 求一个从0 到(n+m+1) 的最短路径就好了,

怎么维护最右侧?:  Dijkstra  有 队列优化!多以我们可以再这个由下级队列里面 吧col 号也设置进去;这样就可以使答案的字典序最大,也就是最右侧:

代码.cpp

  

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <string>
using namespace std;
int n,m;
int mat[105][105];
int dd[][2]={-1,1,  -1,0,  -1,-1,  0,1,  0,-1,  1,1, 1,0, 1,-1 };
int ddd[][2]={1,-1,1,0,1,1};
bool jude(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m;
}
int ID(int x,int y)
{
    return (x-1)*m+y;
}
const int INF = 1000000000;
const int maxn =10000+10;
struct Edge {
  int from, to, dist,col;
  Edge(){}
  Edge(int from,int to,int dist,int col):from(from),to(to),dist(dist),col(col){}
};
struct HeapNode {
  int d, u , col;
  HeapNode(){}
  HeapNode(int d,int u,int col):d(d),u(u),col(col){}
  bool operator < (const HeapNode& rhs) const {
      if(d==rhs.d) return col<rhs.col;
    return d > rhs.d;
  }
};

struct Dijkstra {
  int n, m;
  vector<Edge> edges;
  vector<int> G[maxn];
  bool done[maxn];
  int d[maxn];
  int p[maxn];
  void init(int n) {
    this->n = n;
    for(int i = 0; i < n; i++) G[i].clear();
    edges.clear();
  }
  void AddEdge(int from, int to, int dist,int col) {
    edges.push_back(Edge(from, to, dist,col));
    m = edges.size();
    G[from].push_back(m-1);
  }
  void dijkstra(int s) {
    priority_queue<HeapNode> Q;
    for(int i = 0; i < n; i++) d[i] = INF;
    d[s] = 0;
    memset(done, 0, sizeof(done));
    Q.push( HeapNode(0, s , 0)) ;
    while(!Q.empty()) {
      HeapNode x = Q.top(); Q.pop();
      int u = x.u;
      if(done[u]) continue;
      done[u] = true;
      for(int i = 0; i < G[u].size(); i++) {
        Edge& e = edges[G[u][i]];
        if(d[e.to] > d[u] + e.dist) {
          d[e.to] = d[u] + e.dist;
          p[e.to] = G[u][i];
          Q.push(HeapNode(d[e.to], e.to, e.col));
        }
      }
    }
  }
  void GetShortestPaths(int s, int & dist, vector<int>&paths) {
    dijkstra(s);
    for(int i = n-1; i <n; i++) {
      dist = d[i];
      paths.clear();
      int t = i;
      paths.push_back(t);
      while(t != s) {
        paths.push_back(edges[p[t]].col);
        t = edges[p[t]].from;
      }
      reverse(paths.begin(), paths.end());
    }
  }
};
Dijkstra solver;
vector <int> path;
int main()
{
    int t,ca=1;
    scanf("%d",&t);
    while(t--)
    {

        scanf("%d%d",&n,&m);
        solver.init(n*m+2);
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&mat[i][j]);
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
        {
            for(int k=0;k<3;k++)
            {
                int x=i+ddd[k][0];
                int y=j+ddd[k][1];
                if(!jude(x,y)) continue;
                solver.AddEdge(ID(i,j),ID(x,y),mat[x][y],y);
            }
// 上边有个dd 数组 (用dd数组 8-connected 然后K 变成上届8 就可以了 )
        }
        for(int i=1;i<=m;i++)  solver.AddEdge(0,ID(1,i),mat[1][i],i);
        for(int i=1;i<=m;i++)  solver.AddEdge(ID(n,i),n*m+1,0,105);
        int dis=0;
        solver.GetShortestPaths(0,dis,path);
        printf("Case %d\n",ca++);
        for(int i=0;i<path.size()-2;i++)
        {
            if(i==0) printf("%d",path[i]);
            else     printf(" %d",path[i]);
        }
        puts("");
    }
    return 0;
}

  

时间: 2024-10-01 07:24:42

hdu 5092 Seam Carving的相关文章

hdu 5092 Seam Carving dp+记录路径

Seam Carving Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 605    Accepted Submission(s): 253 Problem Description Fish likes to take photo with his friends. Several days ago, he found that so

hdu 5092 Seam Carving(DP+记录路径)

Seam Carving Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 119    Accepted Submission(s): 69 Problem Description Fish likes to take photo with his friends. Several days ago, he found that som

hdu 5092 Seam Carving 简单DP ”水一炮试试“大法

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5092 非常卡读题 题目中说可以八个方向地走,完全没有提及是从上往下的 需要从样例中猜测”可能只是从上往下“,然后根据现场的过题情况决定要不要水一发试试 对于”水一炮试试“,感觉一般适用于: 1.本题的其他做法未果/很难写,其他的题目没法出 2.码的成本不会很高 3.心态上,得之我幸,失之我命 (水不过的时候,再检查一下水的姿势有没有什么不妥,如果还是不行,就要勇敢地.果断地走出过不了题的不开心-)

hdu 5092 Seam Carving (简单数塔DP,题没读懂,,不过可以分析样例)

题意: 给一个m*n的矩阵,每格上有一个数. 找从第1行到第m行的一条路径,使得这条路径上的数之和最小. 路径必须满足相邻两行所选的两个数的纵坐标相邻(即一个格子必须是另一个格子的周围八个格子中的一个) 输出每一行取的数的列值.  若有多个答案,则路径要求尽量靠右. 思路: 简单数塔DP.题比较不好读,不过可以分析样例. 代码: int T,m,n; int a[105][105], f[105][105]; int path[105]; int main(){ cin>>T; rep(t,1

递推DP HDOJ 5092 Seam Carving

题目传送门 1 /* 2 题意:从上到下,找最短路径,并输出路径 3 DP:类似数塔问题,上一行的三个方向更新dp,路径输出是关键 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <iostream> 8 #include <cstring> 9 #include <cmath> 10 #include <string> 11 #include <vector

hdoj 5092 Seam Carving 【树塔DP变形 + 路径输出】 【简单题】

Seam Carving Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 956    Accepted Submission(s): 382 Problem Description Fish likes to take photo with his friends. Several days ago, he found that so

hdu 5902 Seam Carving

水题,直接上代码了 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cmath> 5 #include<algorithm> 6 #include<set> 7 #include<map> 8 #include<queue> 9 #include<stack> 10 #include<string&g

Seam carving 学习笔记

今天首次接触了图像编辑中的seam carving知识,感觉挺神奇的.虽然我自己可能理解的不是很深刻,但是记录下来,总是好的. seam carving直接翻译过来是“线裁剪”的意思.它的主要用途是对图像进行缩放.不同于传统的按比例缩放图像的方式,seam carving的是内容感知的,它充分考虑了图像中像素的重要性,通过删除或增加seam线来实现图像尺寸的调整.它在缩放不是特别大的情况下,能够很好的保护图像中的显著物体. 具体来说,seam carving定义了穿过整幅图像的像素线(即seam

HDU5092——Seam Carving(动态规划+回溯)(2014上海邀请赛重现)

Seam Carving DescriptionFish likes to take photo with his friends. Several days ago, he found that some pictures of him were damaged. The trouble is that there are some seams across the pictures. So he tried to repair these pictures. He scanned these