dyllalala

导航

[poj 1502]昂贵的聘礼

一道不算太难的最短路喵~

容我吐槽一下,酋长的地位居然不是最高的额——那你特么的居然还算是酋长?!

枚举一个地位区间 [i..i+M-1] 只要所有的交易者的地位都在该区间中,那么就不会引起冲突

而这个可悲的酋长是必须在区间中的,所以若酋长的地位为 L0 那么该枚举的区间就是 [L0-i, L0+M-i] {i|0<=i<=M}

然后就是裸的 dijkstra 了,取出地位在区间中的点,然后新增一个点 N+1,向所有点连边,距离是所有物品的直接价格

若 物品 i 可以通过 物品 j 来降价,那么从 j 向 i 连一条边,距离为降价后的价格

以 N+1 为源点跑一个最短路就可以了

 

我发现带内部调整的优先队列不是蛮好写的嘛~

 

  1 #include <cstdio>
  2 #include <cstring>
  3 const int sizeOfPoint=128;
  4 const int sizeOfEdge=32768;
  5 
  6 int n;
  7 int h[sizeOfPoint];
  8 inline int getint();
  9 inline void putint(int);
 10 
 11 struct edge {int point, dist; edge * next;};
 12 edge memory[sizeOfEdge], * port=memory;
 13 edge * e[sizeOfPoint];
 14 inline edge * newedge(int point, int dist, edge * next)
 15 {
 16     edge * ret=port++;
 17     ret->point=point; ret->dist=dist; ret->next=next;
 18     return ret;
 19 }
 20 inline void link(int u, int v, int d)
 21 {
 22     e[u]=newedge(v, d, e[u]); e[v]=newedge(u, d, e[v]);
 23 }
 24 
 25 struct priority_queue
 26 {
 27     int size, q[sizeOfPoint];
 28     int id[sizeOfPoint];
 29     inline int front() {return q[1];}
 30     inline bool exist(int x) {return id[x]>0;}
 31     inline void down(int i)
 32     {
 33         register int x=q[i];
 34         register int j;
 35         for (j=i<<1;j<=size;i=j, j=i<<1)
 36         {
 37             if (j<size && h[q[j+1]]<h[q[j]]) j++;
 38             if (h[q[j]]<h[x]) id[q[i]=q[j]]=i;
 39             else break;
 40         }
 41         id[q[i]=x]=i;
 42     }
 43     inline void up(int i)
 44     {
 45         register int x=q[i];
 46         register int j;
 47         for (j=i>>1;j;i=j, j=i>>1)
 48             if (h[q[j]]>h[x]) id[q[i]=q[j]]=i;
 49             else break;
 50         id[q[i]=x]=i;
 51     }
 52     inline void build(int _size)
 53     {
 54         size=_size;
 55         for (int i=1;i<=size;i++) id[q[i]=i]=i;
 56         for (int i=size>>1;i;i--) down(i);
 57     }
 58     inline void pop()
 59     {
 60         id[q[1]]=0;
 61         id[q[1]=q[size--]]=1;
 62         down(1);
 63     }
 64     inline void deskey(int x)
 65     {
 66         up(id[x]);
 67     }
 68 };
 69 
 70 inline int min(int x, int y) {return x<y?x:y;}
 71 inline int max(int x, int y) {return x>y?x:y;}
 72 inline void dijkstra();
 73 
 74 
 75 int main()
 76 {
 77     n=getint();
 78     for (int i=2;i<=n;i++)
 79         for (int j=1;j<i;j++)
 80         {
 81             int A=getint();
 82             if (A>=0) link(i, j, A);
 83         }
 84     memset(h, 0x3F, sizeof h); h[1]=0;
 85     dijkstra();
 86 
 87     int ans=0;
 88     for (int i=1;i<=n;i++) ans=max(ans, h[i]);
 89 
 90     putint(ans);
 91 
 92     return 0;
 93 }
 94 inline int getint()
 95 {
 96     register int num=0;
 97     register char ch=0;
 98     do ch=getchar(); while ((ch<'0' || ch>'9') && ch!='x');
 99     if (ch=='x') return -1;
100     do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
101     return num;
102 }
103 inline void putint(int num)
104 {
105     char stack[15];
106     register int top=0;
107     if (num==0) stack[top=1]='0';
108     for ( ;num;num/=10) stack[++top]=num%10+'0';
109     for ( ;top;top--) putchar(stack[top]);
110     putchar('\n');
111 }
112 inline void dijkstra()
113 {
114     priority_queue q;
115     q.build(n);
116     for ( ;q.size; )
117     {
118         int u=q.front(); q.pop();
119         for (edge * i=e[u];i;i=i->next) if (q.exist(i->point) && h[i->point]>h[u]+i->dist)
120         {
121             h[i->point]=h[u]+i->dist;
122             q.deskey(i->point);
123         }
124     }
125 }
本傻装B系列

 

posted on 2014-09-22 21:53  dyllalala  阅读(168)  评论(0编辑  收藏  举报