这题的实质上是最短路径问题。
大意:从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; }