hihocoder 1038

http://hihocoder.com/problemset/problem/1138

题意:有一些岛屿,要从第一个岛屿到第N个岛屿,求最短距离,距离为min(x,y),也就是两个点的X的差值和Y的差值的较小的。

思路:最开始我觉得应该dijstrak可以解决,因为是LEVEL1的,结果超时了,我就想是不是head+dijstrak。。结果是的,不过这个题可以用SPFA做

优化的部分也就是说对于每一个点,拓展4个边就可以,就是x差值最小的两个点,和y差值最小的两个点。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <math.h>
  5 #include <queue>
  6 #include <stdlib.h>
  7 using namespace std;
  8 #define maxn 1000005
  9 #define inf 0x3f3f3f3f
 10
 11 struct Node{
 12     int x,y;
 13     int id;
 14 }de[maxn];
 15 int n,pos;
 16 int head[maxn],dist[maxn];
 17 bool vis[maxn];
 18
 19 int cmp(const void *a,const void *b)
 20 {
 21     return (*(Node *)a).x-(*(Node *)b).x;
 22 }
 23 int cmp2(const void *a,const void *b)
 24 {
 25     return (*(Node *)a).y - (*(Node * )b).y;
 26 }
 27
 28 int abs(int a,int b)
 29 {
 30     if(a>b)
 31         return a-b;
 32     return b-a;
 33 }
 34 int min(int a,int b)
 35 {
 36     return a>b?b:a;
 37 }
 38
 39 struct note {
 40     int v,w,next;
 41 }edge[maxn];
 42
 43 void init()
 44 {
 45     pos = 1;
 46     memset( dist , inf , sizeof( dist ) );
 47     memset( head , -1 , sizeof( head ) );
 48     memset( vis , false ,sizeof( vis ) );
 49 }
 50
 51
 52 void add(int x,int v,int w)    //这是用数组来构建的一个邻接表。不懂可以在纸上模拟一次就行。
 53 {
 54     edge[ pos ].v = v;
 55     edge[ pos ].w = w;
 56     edge[ pos ].next = head[ x ];
 57     head[ x ] = pos++;
 58 }
 59
 60 void spfa()     //标准的spfa模板。如果可能有负权回路的话,那就加个num数组来判断。
 61 {
 62     queue<int >s;
 63     s.push(1);
 64     vis[ 1 ] = true;
 65     dist[ 1 ] = 0;
 66     while(!s.empty())
 67     {
 68         int tmp = s.front();
 69         s.pop();
 70         vis [ tmp ] = false;
 71         for( int i = head[ tmp ] ; i != -1 ; i = edge[ i ].next )
 72         {
 73             if( dist[ edge[ i ].v ] > dist[ tmp ] + edge[ i ].w)
 74             {
 75                 dist[ edge[ i ].v ] = dist[ tmp ] + edge[ i ].w;
 76                 if( !vis[ edge[ i ].v ] )
 77                 {
 78                     s.push( edge[ i ].v );
 79                     vis[ edge[ i ].v ] =true;
 80                 }
 81
 82             }
 83
 84         }
 85     }
 86 }
 87
 88
 89
 90 int main()
 91 {
 92     scanf("%d",&n);
 93     init();
 94     for(int i = 1;i<=n;i++)
 95         scanf("%d%d",&de[i].x,&de[i].y),de[i].id = i;
 96     qsort(de+1,n,sizeof(de[0]),cmp);
 97     for(int i = 1;i<=n;i++)
 98     {
 99         add(de[i].id,de[i+1].id,min(abs(de[i].x,de[i+1].x),abs(de[i].y,de[i+1].y)));
100         add(de[i+1].id,de[i].id,min(abs(de[i].x,de[i+1].x),abs(de[i].y,de[i+1].y)));
101     }
102     qsort(de+1,n,sizeof(de[0]),cmp2);
103     for(int i = 1;i<=n;i++)
104     {
105         add(de[i].id,de[i+1].id,min(abs(de[i].x,de[i+1].x),abs(de[i].y,de[i+1].y)));
106         add(de[i+1].id,de[i].id,min(abs(de[i].x,de[i+1].x),abs(de[i].y,de[i+1].y)));
107     }
108     spfa();
109     printf("%d\n",dist[n]);
110     return 0;
111 }
时间: 2024-10-21 07:42:57

hihocoder 1038的相关文章

hihoCoder #1038 : 01背包(板子题)

#1038 : 01背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说上一周的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的时刻了! 小Ho现在手上有M张奖券,而奖品区有N件奖品,分别标号为1到N,其中第i件奖品需要need(i)张奖券进行兑换,同时也只能兑换一次,为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其中第i件奖品的评分值为value(i),表示他对这件奖品的喜好值.现在他想知道,凭借他手上的这

hihoCoder #1038 : 01背包

思路:直接 DP解的,方式固定. 1 #include <iostream> 2 #include <stdio.h> 3 #include <cstring> 4 #include <string> 5 using namespace std; 6 7 int dp[100005]; 8 int coms[505]; 9 int value[505]; 10 int max(int a, int b){return a>b?a:b;} 11 12 i

hihoCoder - 1038 - 01背包 (经典动态规划问题!!)

#1038 : 01背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说上一周的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的时刻了! 小Ho现在手上有M张奖券,而奖品区有N件奖品,分别标号为1到N,其中第i件奖品需要need(i)张奖券进行兑换,同时也只能兑换一次,为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其中第i件奖品的评分值为value(i),表示他对这件奖品的喜好值.现在他想知道,凭借他手上的这

hihocoder(1038,1043) 01背包与完全背包

动态规划是一直感觉比较模糊的东西,虽然大致上知道是什么一回事,但是离灵活应用还差得远,但貌似比赛中动态规划的题出的特别多,这两个经典问题其实只能算是一个学习动态规划很好的模型.不过万事开头难,关键还是得静下心来多练习. 01背包的状态转移式:f(i, j) = max{f(i-1, j), f(i-1, j-need[i])+value[i]} 直接按照上述的状态转移式申请二维数组进行运算,伪代码如下: fori : 1..N f(0,j) = 0 for i : 1..N for j : 0.

{dp入门}

之前一直比较恐惧dp的题,暑假之前好好从头补一下. 题目链接:HihoCoder - 1037 数字三角形 dp[i][j]表示到第i层第j个房间时累计收集到的最大值,从上到下记忆化搜索即可 状态转移:dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+m[i][j]; 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 i

HihoCoder - 01\完全背包

HihoCoder上有两道背包问题的problem, http://hihocoder.com/problemset/problem/1038 (01背包) #include <cmath> #include <cstdio> #include <vector> #include <string> #include <iostream> #include <algorithm> #include <unordered_map&g

[hihocoder]01背包 accept 与 time limit exceed的代码比较

链接:http://hihocoder.com/problemset/problem/1038?sid=469496 accept代码: 1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 int dp[501][100001]; 6 int need[501]; 7 int value[501]; 8 9 int main() 10 { 11 int num,amount; 12 cin&

01背包***hihocoder

题目来自hihocoder http://hihocoder.com/problemset/problem/1038 描述 且说上一周的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的时刻了! 小Ho现在手上有M张奖券,而奖品区有N件奖品,分别标号为1到N,其中第i件奖品需要need(i)张奖券进行兑换,同时也只能兑换一次,为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其中第i件奖品的评分值为value(i),表示他对这件奖品的喜好值.现在他想

[hihoCoder#1381]Little Y&#39;s Tree

[hihoCoder#1381]Little Y's Tree 试题描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每次小J会删掉这个树中的k条边,这棵树被分成k+1个连通块.小J想知道每个连通块中最远点对距离的和. 这里的询问是互相独立的,即每次都是在小Y的原树上进行操作. 输入 第一行一个整数n,接下来n-1行每行三个整数u,v,w,其中第i行表示第i条边边权为wi,连接了ui,vi两点. 接下来一行一个整数q,表示有q组询问. 对于每组询问,第一行一个正整数k,接下来一