cogs1000 伊吹萃香 二维最短路
链接:http://cogs.pro/cogs/problem/problem.php?pid=1000
题意:有n个点,每一秒钟会从黑变白或从白变黑,黑到白额外费体力,白到黑省体力,还可以停在某个点,停白点不费体力,停黑点费体力,求到n点最省体力的多少。
初看这道题我们可能会被琐碎的情况搞晕,但是我们仔细观察可以发现:每一个点只有黑点白点两种情况,而且黑点之后一定是白点,白点之后一定是黑点,奇数秒颜色一样,偶数秒颜色一样。
因此思路便可得出:把每个点拆成奇数秒的点和偶数秒的点,每个点建边时只建下一秒到的点,停在本点就是奇点到偶点,偶点到奇点。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(){;}
只要是活着的东西,就算是神我也杀给你看。