日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LightOJ - 1074 Extended Traffic(最短路+判断负环)

發布時間:2024/4/11 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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(最短路+判断负环)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。