标签:return out dijkstra 算法 jks printf 更新 blank stream
图论题-单源最短路径:添加一个顶点,连接各个救火团队所在的救火点,路径长度均设为 0,设该顶点为源,即变成了单源最短路径问题。使用两次Dijkstra算法可求出两个最短路径 的最大值。比较时将救火团队的乘以C进行比较可避免分数操作。
#include<iostream> #include<string.h> #include<algorithm> #include<math.h> #define INF 0x3f3f3f3f using namespace std; int vis[1005],way[1005][1005],dis[1005],a[1005]; int n,m; //vis[i]标记已经处理过的点,dis[j]记录起点s到点j最近的距离,way[][]表示路径关系 void init() { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) way[i][j]=0; else way[i][j]=INF; } } } void Dijkstra(int s) { int mn; for (int i = 1; i <= n; i++)//初始化 { vis[i] = 0; dis[i] = way[s][i]; } vis[s] = 1; for (int i = 1; i <= n; i++) { int u; mn = INF; u = -1; for (int j = 1; j <= n; j++)//找出离初始起点s直接距离最近的点,记录下标和最近距离 { if (vis[j] == 0 && dis[j] < mn) { u = j; mn = dis[j]; } } if (u == -1)//如果没有找到 break; vis[u] = 1; for (int j = 1; j <= n; j++)//更新 { if (vis[j] == 0) { if (dis[u] + way[u][j] < dis[j]) dis[j] = dis[u] + way[u][j]; } } } } int main() { int t; scanf("%d",&t); while(t--) { int s,k,c; scanf("%d%d%d%d%d",&n,&m,&s,&k,&c);//n是起火点的个数,m是边数,s是消防英雄所在位置,k个消防队,c是系数 for(int i=0;i<k;i++) scanf("%d",&a[i]); init(); for(int i=0;i<m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); if(way[x][y]>z) { way[x][y]=z; way[y][x]=z; } } Dijkstra(s); int ans1=0; for(int i=1;i<=n;i++)//消防英雄到各个起火点距离的最大值 ans1=max(ans1,dis[i]); for(int i=0;i<k;i++)//把n个消防队连接起来,变成一个点 { for(int j=0;j<k;j++) way[a[i]][a[j]]=0; } Dijkstra(a[0]); int ans2=0; for(int i=1;i<=n;i++)//遍历消防队到各个起火点距离的最大值 ans2=max(ans2,dis[i]); if(ans1>ans2*c) printf("%d\n",ans2); else printf("%d\n",ans1); } return 0; }
题意:有n张连续的牌,一次操作m张牌,q次询问,每次询问数字为x的牌在洗牌之前的位置。
操作是:先把n张牌洗牌之后放在桌面上,每次从桌面拿一张牌到手中,拿完一张牌之后,把桌面上面的m张牌一次放到最底下,重复操作,直到拿完桌面上的所有牌;
最后手上的牌的顺序是依次递减的
题解:用队列逆向模拟还原即可:从第n张牌开始,把第n张牌从手里放到桌面之后,把最底下的牌放到最顶上,然后把第n-1张牌放到桌面,再把最底下的牌放到最顶上,直到手里没有牌
#include<iostream> #include<queue> using namespace std; int n,m,t,k; int b[40000005]; int q[40000005]; int main() { cin>>t; while(t--) { cin>>n>>m>>k; queue<int>p; for(int i=0;i<k;i++) cin>>q[i]; for(int i=n;i>=1;i--) { if(!p.empty()) { for(int j=1;j<=m;j++) { int top=p.front(); p.pop(); p.push(top); } } p.push(i); } for(int i=n;i>=1;i--) { int now=p.front(); b[i]=now; p.pop(); } for(int i=0;i<k;i++) cout<<b[q[i]]<<endl; } return 0; }
标签:return out dijkstra 算法 jks printf 更新 blank stream
原文地址:https://www.cnblogs.com/-citywall123/p/11494569.html