bzoj2662: [BeiJing wc2012]冻结 最短路 建图

好久没有1A题啦♪(^∇^*)

一个sb建图,我居然调样例调了10min

看起来是双向边,其实在建图的时候要当成有向图,

否则他会时间倒流(233)

把每个点裂成k个点,然后把每条边裂成4条边(正向反向&膜不膜)

(话说我好像不会用openlivewriter贴代码,尴尬了)

 1 #include <bits/stdc++.h>
 2 #define poi(x,y) ((x)*(k+1)+(y))
 3 #define st poi(1,0)
 4 #define INF 2000000000
 5 using namespace std;
 6 int n,m,k,E;
 7 int from[2000001],to[2000001],nex[2000001];
 8 int fir[2000001],d[2000001],w[2000001];
 9 void add(int x,int y,int z)
10 {
11     from[++E]=x;to[E]=y;w[E]=z;nex[E]=fir[x];fir[x]=E;
12 }
13 int work()
14 {
15     for(int i=1;i<=poi(n,k);i++)
16         d[i]=INF;
17     d[st]=0;
18     priority_queue<pair<int,int> > q;
19     for(int i=fir[st];i;i=nex[i])
20         q.push(make_pair(-w[i],i));
21     while(!q.empty())
22     {
23         int tem=q.top().second;q.pop();
24         if(to[tem]>=poi(n,0))
25             int e=1;
26         if(d[from[tem]]!=INF && d[from[tem]]+w[tem]<d[to[tem]])
27         {
28             d[to[tem]]=d[from[tem]]+w[tem];
29             for(int i=fir[to[tem]];i;i=nex[i])
30                 q.push(make_pair(-w[i],i));
31         }
32     }
33     return d[poi(n,k)];
34 }
35 int main()
36 {
37     scanf("%d%d%d",&n,&m,&k);
38     for(int i=1;i<=m;i++)
39     {
40         int from,to,wei;
41         scanf("%d%d%d",&from,&to,&wei);
42         for(int j=0;j<k;j++)
43             add(poi(from,j),poi(to,j+1),wei/2),
44             add(poi(to,j),poi(from,j+1),wei/2);
45         for(int j=0;j<=k;j++)
46             add(poi(from,j),poi(to,j),wei),
47             add(poi(to,j),poi(from,j),wei);
48     }
49     for(int i=0;i<k;i++)
50         add(poi(n,i),poi(n,k),0);
51     printf("%d\n",work());
52     return 0;
53 } 

 

posted @ 2017-08-10 09:08  汪立超  阅读(167)  评论(0编辑  收藏  举报