这题的实质上是最短路径问题。
大意:从1到N的路程总花费小于等于K的最短路径。
每条路有花费和长度。
依旧采用迪杰斯特拉的贪心思路,每次贪最短的,根据这个点来更新其他的点。
这题我没有注意的是加限制的优先队列的性质:
优先队列的元素保证都是到目标点的花费小于等于K的,这样下来,以长度为第一维度排序的优先队列,第一次到达目标点为终点的时候,此时的len即为所求。
我在这个点坑爹的TLE了。另外由于没有消掉文件读写WA了两次。
#include<iostream>
#include<queue>
#define INF 0x3FFFFFFF
using namespace std;struct ROADS
{int v,len,roll;int next;ROADS(){next=-1;}
}road[22222];int ptr[111];struct NODE
{
//public:int v,len,roll;friend bool operator <( NODE a,NODE b ){return a.len>b.len;}NODE( int a=0,int b=0,int c=0 ){v=a;len=b;roll=c;}
};
int Ecnt;void addEdge( int u,int v,int len,int roll )
{road[Ecnt].v=v;road[Ecnt].len=len;road[Ecnt].roll=roll;road[Ecnt].next=ptr[u];ptr[u]=Ecnt++;
}int main()
{//freopen( "test.in","r",stdin );//freopen( "ans.out","w",stdout );int K,N,R;while( scanf("%d %d %d",&K,&N,&R )!=EOF ){memset( ptr,-1,sizeof(ptr) );Ecnt=0;int u,v,len,roll;for( int i=0;i<R;i++ ){scanf( "%d %d %d %d",&u,&v,&len,&roll );addEdge( u,v,len,roll );//addEdge( v,u,len,roll );}priority_queue<NODE> PQ;NODE temp(1,0,0);PQ.push(temp);int ans=-1;while( !PQ.empty() )//按dijstra每次取出最短的 {NODE cur=PQ.top();PQ.pop();if( cur.v==N ){ans=cur.len;break;}for( int i=ptr[cur.v];i!=-1;i=road[i].next ){if( cur.roll+road[i].roll<=K ){temp.v=road[i].v;temp.len=cur.len+road[i].len;temp.roll=cur.roll+road[i].roll;PQ.push(temp);}}}printf( "%d\n",ans );}return 0;
}