LightOJ 1074 - Extended Traffic 【SPFA】
阿新 • • 發佈:2018-09-01
set dijk 否則 出現 ont empty tps ffi 題目
<題目鏈接>
題目大意:
有n個城市,每一個城市有一個擁擠度Ai,從一個城市I到另一個城市J的時間為:(A(v)-A(u))^3。問從第一個城市到達第k個城市所花的時間,如果不能到達,或者時間小於3輸出?否則輸出所花的時間。
解題分析:
很明顯,此題路段的權值可能為負,所以我們就不能用Dijkstra算法求最短路了。需要註意的是,當點存在負環的時候,就要將負環所能夠到達的所有點全部標記,從起點到這些點的最短路是不存在的(因為假設如果存在最短路,那麽只要途中在負環上多走幾遍,那麽重新算得的時間一定會變少,所以不存在最短路)。所以,總的來說,對於本題,對那些負環能夠到達的點,和從起點無法到達的點,和時間小於3的點,全部輸出“?”,其他滿足條件的直接輸出最短時間就行。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std; const int MAXN=220; const int INF =0x3f3f3f3f; struct Edge{ int to; int next; int val; }edge[MAXN*MAXN]; int res,n; int head[MAXN]; boolvis[MAXN]; //記錄該點是否在隊列內 bool cir[MAXN]; //記錄該點是否為負環上的點 int a[MAXN],dist[MAXN],cnt[MAXN]; //cnt[]數組記錄該數在隊列中出現的次數 void dfs(int u){ //將該負環所能夠達到的所有點全部標記 cir[u]=true; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(!cir[v])dfs(v); } } void init(){ memset(head,-1,sizeof(head)); res=0; } void add(int u,int v,int w){ edge[res].to=v,edge[res].val=w; edge[res].next=head[u]; head[u]=res++; } void SPFA(int st){ memset(vis,false,sizeof(vis)); memset(cir,false,sizeof(cir)); for(int i=1;i<=n;i++) dist[i]=INF; vis[st]=true; dist[st]=0; queue<int>q; q.push(st); memset(cnt,0,sizeof(cnt)); cnt[st]=1; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=false; //當該點從隊列中pop掉之後,就要清除vis標記 for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(cir[v])continue; //如果是負環上的點 if(dist[v]>dist[u]+edge[i].val){ dist[v]=dist[u]+edge[i].val; if(!vis[v]){ //如果該點不在隊列中 vis[v]=true; q.push(v); cnt[v]++; if(cnt[v]>n){ //若存在負環,就用dfs將該負環能夠達到的所有點標記 dfs(v); } } } } } } int main(){ int t;scanf("%d",&t); int ncase=0; while(t--){ init(); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int m; scanf("%d",&m); while(m--){ int u,v; scanf("%d %d",&u,&v); add(u,v,(a[v]-a[u])*(a[v]-a[u])*(a[v]-a[u])); } SPFA(1); printf("Case %d:\n",++ncase); scanf("%d",&m); while(m--){ int u;scanf("%d",&u); if(cir[u] || dist[u]<3 || dist[u] == INF) //如果詢問的點能由負環達到、或者到起點的最小受益小於3、或者詢問的點不可達 printf("?\n"); else printf("%d\n",dist[u]); } } return 0; }
2018-08-31
LightOJ 1074 - Extended Traffic 【SPFA】