LightOJ - 1074 Extended Traffic(最短路+判断负环)
生活随笔
收集整理的這篇文章主要介紹了
LightOJ - 1074 Extended Traffic(最短路+判断负环)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出n個城市,每個城市都有一個擁擠度,從a到b的時間是(b的擁擠度-a的擁擠度)^3,點1為起點,求最短時間
題目分析:這個題第一感覺是個裸題,n還非常小,偷了個懶上了一發floyd,果不其然的WA了,回頭去檢查代碼發現沒有什么問題,去查了題解才知道原來是漏了一個很重要的細節,就是在處理邊權上,(b的擁擠度-a的擁擠度)^3可能會出現負值,這樣就會導致負環的出現,而一旦存在負環,則負環上的所有點都不可能存在最短路的,所以最后判斷條件只要是最短路小于3或等于inf或位于負環上都輸出問號,其他情況輸出最小值即可。
這里放上兩個代碼,都是從網上新學的如何標記負環,以前都是用spfa判斷負環,這個題要求的是標記負環,算是一個小變形吧
代碼1:用cnt數組維護入隊次數:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<sstream> #include<cmath> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=210;int n;struct Node {int w,to;Node(int TO,int W){to=TO;w=W;} };vector<Node>node[N];int maze[N][N];int a[N];int d[N];bool vis[N];int cnt[N];int dist(int i,int j) {return (a[j]-a[i])*(a[j]-a[i])*(a[j]-a[i]); }void spfa() {memset(vis,false,sizeof(vis));memset(d,inf,sizeof(d));memset(cnt,0,sizeof(cnt));d[1]=0;vis[1]=true;queue<int>q;cnt[1]++;q.push(1);while(!q.empty()){int tem=q.front();q.pop();vis[tem]=false;for(int i=0;i<node[tem].size();i++){Node temp=node[tem][i];if(d[temp.to]>d[tem]+temp.w){d[temp.to]=d[tem]+temp.w;if(!vis[temp.to]&&cnt[temp.to]<=n-1)//標記所有負環上的點 {vis[temp.to]=true;q.push(temp.to);cnt[temp.to]++;}}}} }int main() { // freopen("input.txt","r",stdin);int w;cin>>w;int kase=0;while(w--){scanf("%d",&n);for(int i=1;i<=n;i++){node[i].clear();scanf("%d",a+i);}int m;scanf("%d",&m);for(int i=1;i<=m;i++){int a,b;scanf("%d%d",&a,&b);int dd=dist(a,b);node[a].push_back(Node(b,dd));}spfa(); int q;scanf("%d",&q);printf("Case %d:\n",++kase);while(q--){int p;scanf("%d",&p);if(d[p]<3||d[p]==inf||cnt[p]>=n-1)//注意這里的判斷條件cout<<"?"<<endl;elsecout<<d[p]<<endl;}}return 0; }代碼2:用book數組標記負環上的點(用dfs搜索所有負環可到達的點:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<sstream> #include<cmath> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=210;int n;struct Node {int w,to;Node(int TO,int W){to=TO;w=W;} };vector<Node>node[N];int maze[N][N];int a[N];int d[N];bool vis[N];int cnt[N];bool book[N];int dist(int i,int j) {return (a[j]-a[i])*(a[j]-a[i])*(a[j]-a[i]); }void dfs(int u) {book[u]=true;for(int i=0;i<node[u].size();i++){if(!book[node[u][i].to])dfs(node[u][i].to);} }void spfa() {memset(vis,false,sizeof(vis));memset(d,inf,sizeof(d));memset(cnt,0,sizeof(cnt));memset(book,false,sizeof(book));d[1]=0;vis[1]=true;queue<int>q;cnt[1]++;q.push(1);while(!q.empty()){int tem=q.front();q.pop();vis[tem]=false;for(int i=0;i<node[tem].size();i++){Node temp=node[tem][i];if(d[temp.to]>d[tem]+temp.w){d[temp.to]=d[tem]+temp.w;if(!vis[temp.to])//標記所有負環上的點 {vis[temp.to]=true;q.push(temp.to);cnt[temp.to]++;if(cnt[temp.to]>n-1){dfs(temp.to);//搜索所有與該點相連的點,并做好標記return;}}}}} }int main() { // freopen("input.txt","r",stdin);int w;cin>>w;int kase=0;while(w--){scanf("%d",&n);for(int i=1;i<=n;i++){node[i].clear();scanf("%d",a+i);}int m;scanf("%d",&m);for(int i=1;i<=m;i++){int a,b;scanf("%d%d",&a,&b);int dd=dist(a,b);node[a].push_back(Node(b,dd));}spfa(); int q;scanf("%d",&q);printf("Case %d:\n",++kase);while(q--){int p;scanf("%d",&p);if(d[p]<3||d[p]==inf||book[p])//注意這里的判斷條件cout<<"?"<<endl;elsecout<<d[p]<<endl;}}return 0; }?
總結
以上是生活随笔為你收集整理的LightOJ - 1074 Extended Traffic(最短路+判断负环)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 1847 Tram(最短路)
- 下一篇: HDU - 4725 The Short