传送门:http://poj.org/problem?id=1724
注意有重边!
①Dijsktra+优先队列(16ms):
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int maxn=10010; int T,n,k,r,e; int head[maxn]; struct Edge{//链式前向星建图 int v,w,c; int next; }edge[maxn]; void init(){ e=0; memset(head,-1,sizeof(head)); } void addEdge(int u,int v,int w,int c){ edge[e].v=v,edge[e].w=w,edge[e].c=c,edge[e].next=head[u]; head[u]=e++; } struct node{ int n; int dis;//表示源点到点n的最小距离 int cost;//表示源点到点n的最小费用 bool operator<(const node&a)const{//重载运算符 return (a.dis<dis)||(dis==a.dis&&a.cost<cost); } }; void Dijsktra(){ priority_queue<node>Q; node s,e; s.n=1,s.dis=0,s.cost=0;//初始化 Q.push(s); while(!Q.empty()){ s=Q.top();Q.pop(); if(s.n==n){//已经更新到最优解,返回结果 printf("%d\n",s.dis); return ; } int u=s.n; for(int i=head[u];i!=-1;i=edge[i].next){ e.n=edge[i].v; e.dis=s.dis+edge[i].w; e.cost=s.cost+edge[i].c; if(e.cost<=k){//判断所消耗费用是否满足条件 Q.push(e); } } } printf("-1\n");//不存在最优解,输出-1 return ; } int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif while(~scanf("%d%d%d",&k,&n,&r)){ init(); int u,v,w,c; while(r--){ scanf("%d%d%d%d",&u,&v,&w,&c); addEdge(u,v,w,c); } Dijsktra(); } return 0; }
②Dfs(125ms):
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int maxn=10010; int T,n,k,r; int e,ans; int head[maxn]; bool vis[105]; struct Edge{//链式前向星建图 int v,w,c; int next; }edge[maxn]; void init(){ e=0; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); } void addEdge(int u,int v,int w,int c){ edge[e].v=v,edge[e].w=w,edge[e].c=c,edge[e].next=head[u]; head[u]=e++; } void Dfs(int u,int dis,int cost){ if(cost>k) return ; if(dis>ans) return ; if(u==n){ ans=dis; return ; } for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(!vis[v]){ vis[v]=1; Dfs(v,dis+edge[i].w,cost+edge[i].c); vis[v]=0; } } } int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif while(~scanf("%d%d%d",&k,&n,&r)){ init(); int u,v,w,c; while(r--){ scanf("%d%d%d%d",&u,&v,&w,&c); addEdge(u,v,w,c); } ans=INF; Dfs(1,0,0); if(ans==INF) printf("-1\n"); else printf("%d\n",ans); } return 0; }