cogs1000 伊吹萃香 二维最短路

链接:http://cogs.pro/cogs/problem/problem.php?pid=1000

题意:有n个点,每一秒钟会从黑变白或从白变黑,黑到白额外费体力,白到黑省体力,还可以停在某个点,停白点不费体力,停黑点费体力,求到n点最省体力的多少。

初看这道题我们可能会被琐碎的情况搞晕,但是我们仔细观察可以发现:每一个点只有黑点白点两种情况,而且黑点之后一定是白点,白点之后一定是黑点,奇数秒颜色一样,偶数秒颜色一样。

因此思路便可得出:把每个点拆成奇数秒的点和偶数秒的点,每个点建边时只建下一秒到的点,停在本点就是奇点到偶点,偶点到奇点。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn=5005,maxm=30005;
 7 int n,m,dis[maxn<<1],id[maxn<<1],wei[maxn<<1];
 8 struct node
 9 {
10     int from,to,weight,next;
11 }edge[(maxm<<1)+maxn];
12 int head[maxn<<1],tot;
13 void addedge(int u,int v,int w)
14 {
15     edge[++tot]=(node){u,v,w,head[u]};head[u]=tot;
16 }
17 #include<queue>
18 bool inq[maxn<<1];
19 void SPFA()
20 {
21     memset(dis,0x3f,sizeof(dis));
22     dis[1]=0;
23     queue<int>q;q.push(1);
24     inq[1]=1;
25     while(!q.empty())
26     {
27         int k=q.front();q.pop();inq[k]=0;
28         for(int i=head[k];i;i=edge[i].next)
29         {
30             int v=edge[i].to;
31             if(dis[v]>dis[k]+edge[i].weight)
32             {
33                 dis[v]=dis[k]+edge[i].weight;
34                 if(!inq[v])
35                 {
36                     inq[v]=1;
37                     q.push(v);
38                 }
39             }
40         }
41     }
42 }
43 int haha()
44 {
45     freopen("suika.in","r",stdin);
46     freopen("suika.out","w",stdout);
47     scanf("%d%d",&n,&m);
48     for(int i=1;i<=n;i++)
49     {
50         int x;scanf("%d",&x);
51         id[(i<<1)-1]=x;id[(i<<1)]=x^1;
52     }
53     for(int i=1;i<=n;i++)
54     {
55         scanf("%d",&wei[(i<<1)]);
56         wei[(i<<1)-1]=wei[(i<<1)];
57     }
58     for(int i=1;i<=n;i++)
59     {
60         int x;scanf("%d",&x);
61         if(id[(i<<1)])
62         {
63             addedge(i<<1,(i<<1)-1,x);
64             addedge((i<<1)-1,i<<1,0);
65         }
66         else
67         {
68             addedge(i<<1,(i<<1)-1,0);
69             addedge((i<<1)-1,i<<1,x);
70         }
71     }
72     for(int i=1;i<=m;i++)
73     {
74         int u,v,w;scanf("%d%d%d",&u,&v,&w);
75         if(id[(u<<1)]&&!id[(v<<1)])
76         {
77             addedge(u<<1,(v<<1)-1,w+abs(wei[(u<<1)]-wei[(v<<1)]));
78             addedge((u<<1)-1,v<<1,max(w-abs(wei[(u<<1)]-wei[(v<<1)]),0));
79         }
80         else if(!id[(u<<1)]&&id[(v<<1)])
81         {
82             addedge(u<<1,(v<<1)-1,max(w-abs(wei[(u<<1)]-wei[(v<<1)]),0));
83             addedge((u<<1)-1,v<<1,w+abs(wei[(u<<1)]-wei[(v<<1)]));
84         }
85         else
86         {
87             addedge(u<<1,(v<<1)-1,w);
88             addedge((u<<1)-1,v<<1,w);
89         }
90     }
91     SPFA();
92     printf("%d\n",min(dis[(n<<1)-1],dis[(n<<1)]));
93 }
94 int sb=haha();
95 int main(){;}
cogs 1000

 

posted @ 2017-07-26 06:42  ccc000111  阅读(225)  评论(0编辑  收藏  举报