zoukankan      html  css  js  c++  java
  • POJ 3411 Paid Roads

    Description

    A network of m roads connects N cities (numbered from 1 to N). There may be more than one road connecting one city with another. Some of the roads are paid. There are two ways to pay for travel on a paid road i from city ai to city bi:

    in advance, in a city ci (which may or may not be the same as ai);
    after the travel, in the city bi.

    The payment is Pi in the first case and Ri in the second case.

    Write a program to find a minimal-cost route from the city 1 to the city N.

    解题报告:
    这个题花了很久不知道错在哪,后来发现对题目意思理解不是很透彻,仿佛他经过一个点Ci一次只能获得走i这条边的机会,然后可以在Ci一次性买多次,我写的spfa,状态表示为f[i][j] 表示在i这个点,可以经过的边的状态为j的最小费用,然后发现j不能表示为0/1,可以为2/3及以上,最后改写成深搜并改变状态即可

    WA的SPFA:

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=500,M=1<<11;
    int n,m,head[N],num=0,nxt[N<<1],to[N<<1],dis[N<<1],id[N<<1];
    int NXT[N<<1],To[N<<1],Head[N],NUM=0,Pai[N<<1];
    void addlink(int x,int y,int paid){
    	NXT[++NUM]=Head[x];To[NUM]=1<<(y-1);Pai[NUM]=paid;Head[x]=NUM;
    }
    void link(int x,int y,int z,int ids){
    	nxt[++num]=head[x];to[num]=y;
    	id[num]=1<<(ids-1);dis[num]=z;head[x]=num;
    }
    struct node{
    	int x,t;
    	node(){}
    	node(int _x,int _t){x=_x;t=_t;}
    }q[1000005];
    int mod=1000005,f[N][M];bool vis[N][M];
    void spfa(){
    	int t=0,sum=1,x,k,u,kis,paid;
    	memset(f,127/3,sizeof(f));
    	q[1].x=1;q[1].t=0;f[1][0]=0;vis[1][0]=true;
    	while(t!=sum){
    		t++;if(t==mod)t=0;
    		x=q[t].x;k=q[t].t;
    		for(int i=head[x];i;i=nxt[i]){
    			u=to[i];
    			if(k&id[i]){
    				kis=k-id[i];paid=0;
    			}
    		  else kis=k,paid=dis[i];
    			if(f[x][k]+paid<f[u][kis]){
    				f[u][kis]=f[x][k]+paid;
    				if(!vis[u][kis]){
    					vis[u][kis]=true;
    					sum++;if(sum==mod)sum=0;
    					q[sum]=node(u,kis);
    				}
    			}
    		}
    		for(int i=Head[x];i;i=NXT[i]){
    			u=To[i];if(u&k)continue;
    			kis=u|k;
    			if(f[x][k]+Pai[i]<f[x][kis]){
    				f[x][kis]=f[x][k]+Pai[i];
    				if(!vis[x][kis]){
    					vis[x][kis]=true;
    					sum++;if(sum==mod)sum=0;
    					q[sum]=node(x,kis);
    				}
    			}
    		}
    		vis[x][k]=false;
    	}
    }
    void work()
    {
    	int x,y,c,p,r;
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d%d%d",&x,&y,&c,&p,&r);
    		link(x,y,r,i);addlink(c,i,p);
    	}
    	spfa();
    	int ans=2e8,lim=1<<m;
    	for(int i=0;i<lim;i++){
    		if(f[n][i]<ans)ans=f[n][i];
    	}
    	if(ans==2e8)puts("impossible");
    	else printf("%d
    ",ans);
    }
    
    int main()
    {
    	while(~scanf("%d%d",&n,&m))
    		work();
    	return 0;
    }
    
    

    深搜:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const int maxn = 15;
    struct edge
    {
    	int v,c,p,r,next;
    }edges[maxn];
    int head[maxn];
    int vispath[maxn];
    int n,m,e,ans;
    
    void addedge(int u,int v,int c,int p,int r)
    {
    	edges[e].v = v; edges[e].c = c; edges[e].p = p; edges[e].r = r;
    	edges[e].next = head[u];
    	head[u] = e++;
    }
    
    void dfs(int u,int cost)
    {
    	if(cost > ans) return;
    	if(u == n)
        {
    			if(cost < ans) ans = cost;
    			return;
        }
    	for(int i=head[u];i!=-1;i=edges[i].next)
        {
    			int v = edges[i].v;
    			if(vispath[v]<=3)
            {
    					vispath[v]++;
    					if(vispath[edges[i].c]>0) dfs(v,cost+edges[i].p);
    					else dfs(v,cost+edges[i].r);
    					vispath[v]--;
            }
        }
    }
    
    int main()
    {
    	freopen("pp.in","r",stdin);
    	int u,v,c,p,r;
    	e = 0;
    	memset(head,-1,sizeof(head));
    	scanf("%d%d",&n,&m);
    	for(int i=0;i<m;i++)
    		{
    			scanf("%d%d%d%d%d",&u,&v,&c,&p,&r);
    			addedge(u,v,c,p,r);
    		}
    	ans = 99999999;
    	vispath[1] = 1;
    	dfs(1,0);
    	if(ans < 99999999) printf("%d
    ",ans);
    	else printf("impossible
    ");
    	return 0;
    }
    
    
  • 相关阅读:
    OC学习小总结
    导航控制器
    稍微完善了一些的简单计算器的设计
    android端腾讯性能监控框架Matrix源码分析之第一篇
    android MVP模式介绍与实战
    android声音检测仪---分贝仪 (附源码)
    我的几个开源项目
    结合支付宝和微信首页巩固android事件分发机制 (附项目源码)
    SLAM论文阅读笔记
    Python之可迭代对象、迭代器、生成器
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7500787.html
Copyright © 2011-2022 走看看