Codevs 1021 玛丽卡==洛谷 P1186
来源:互联网 发布:监控软件手机版 编辑:程序博客网 时间:2024/05/29 19:03
麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。
因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。
在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。
麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。
玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。
编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。
第一行有两个用空格隔开的数N和M,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N*(N-1)/2。城市用数字1至N标识,麦克在城市1中,玛丽卡在城市N中。
接下来的M行中每行包含三个用空格隔开的数A,B和V。其中1≤A,B≤N,1≤V≤1000。这些数字表示在A和城市B中间有一条双行道,并且在V分钟内是就能通过。
输出文件的第一行中写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。
5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10
27
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 int map[1000][1000],pre[1010],dis[1010],lu[1010]; 7 int n,m,tot,ans=0; 8 bool exist[1010]; 9 void SPFA(int s)10 {11 queue<int> q;12 memset(dis,0x3f,sizeof(dis));13 memset(exist,false,sizeof(exist));14 dis[1]=0;exist[s]=true;q.push(s);15 while(!q.empty()){16 int x=q.front();q.pop();17 exist[x]=false;18 for(int i=1;i<=n;i++)19 {20 if(dis[i]>dis[x]+map[x][i]){21 dis[i]=dis[x]+map[x][i];pre[i]=x;22 if(exist[i]==false){23 q.push(i);exist[i]=true;24 }25 }26 }27 }28 }29 void dij()30 {31 int minl,k;32 memset(dis,0x3f,sizeof(dis));33 memset(exist,false,sizeof(exist));34 dis[1]=0;35 for(int i=1;i<=n;i++)36 {37 minl=0x5f;38 for(int j=1;j<=n;j++)39 if(exist[j]==false&&dis[j]<minl)40 k=j,minl=dis[j];41 exist[k]=true;42 for(int j=1;j<=n;j++)43 if(map[k][j]!=0&&dis[j]>dis[k]+map[k][j])44 dis[j]=dis[k]+map[k][j];45 }46 }47 int main()48 {49 scanf("%d%d",&n,&m);50 for(int i=1,x,y,z;i<=m;i++){51 scanf("%d%d%d",&x,&y,&z);52 map[x][y]=map[y][x]=z;53 }54 pre[1]=0;55 SPFA(1);56 ans=max(ans,dis[n]);57 ++tot;lu[tot]=n;58 int p=n;59 while(pre[p]!=0){60 ++tot;61 lu[tot]=pre[p];62 p=pre[p];63 }64 for(int i=1;i<=tot-1;i++){65 int k=map[lu[i]][lu[i+1]];66 map[lu[i]][lu[i+1]]=0;67 map[lu[i+1]][lu[i]]=0;68 dij();69 ans=max(ans,dis[n]);70 map[lu[i]][lu[i+1]]=k;71 map[lu[i+1]][lu[i]]=k;72 }73 printf("%d",ans);74 return 0;75 }
以上是我的代码 本人认为没毛病,求大神解救~~
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int maxn = 1005; 8 const int maxm = maxn*(maxn - 1)/2; 9 struct Edge10 {11 int u,v,w,next;12 } edge[maxm];13 int head[maxm],vis[maxn],dis[maxn],prev[maxn];14 int N,M,tot = 0,res;15 16 void addedge(int u,int v,int w)17 {18 edge[tot] = (Edge)19 {20 u,v,w,head[u]21 };22 head[u] = tot++;23 }24 25 int spfa(int x,int y) //虽然玛丽卡在第N个城市,但是1-N的最短距离固定,26 { // 所以我们可以从第1个城市出发,求出1-N的最短路27 memset(dis,0x3f,sizeof(dis));28 memset(vis,0,sizeof(vis));29 queue<int>que;30 dis[1] = 0;31 que.push(1);32 vis[1] = 1;33 while (!que.empty())34 {35 int u = que.front();36 que.pop();37 vis[u] = 0;38 for (int i = head[u]; i != -1; i = edge[i].next)39 {40 int v = edge[i].v;41 if ((u == x && v == y) || (u == y && v == x)) continue;42 if (dis[u] + edge[i].w < dis[v])43 {44 dis[v] = dis[u] + edge[i].w;45 prev[v] = u; //记录前驱(路径)46 if (!vis[v])47 {48 que.push(v);49 vis[v] = 1;50 }51 }52 }53 }54 return dis[N];55 }56 57 int main()58 {59 60 int u,v,w;61 memset(head,-1,sizeof(head));62 memset(prev,0,sizeof(prev));63 scanf("%d%d",&N,&M);64 for (int i = 0; i < M; i++)65 {66 scanf("%d%d%d",&u,&v,&w);67 addedge(u,v,w);68 addedge(v,u,w);69 }70 res = spfa(0,0);71 int tmp = N;72 queue<int>q;73 while (tmp)74 {75 q.push(tmp);76 tmp = prev[tmp];77 }78 while (q.size() > 1)79 {80 tmp = q.front();81 q.pop();82 res = max(res,spfa(tmp,q.front()));83 }84 printf("%d\n",res);85 return 0;86 }
我们可以用一遍SPFA,求出最短路,然后不难发现,炸最短路上的边可以是答案变得更大,而炸掉非最短路上的边对答案没任何影响
- Codevs 1021 玛丽卡==洛谷 P1186
- 玛丽卡 (codevs p1021;洛谷p1186)
- 洛谷 P1186 玛丽卡
- 洛谷 P1186 玛丽卡
- 洛谷 P1186 玛丽卡
- 洛谷 P1186 玛丽卡
- 洛谷 P1186 玛丽卡
- 【洛谷 P1186】玛丽卡 spfa+删边
- P1186 玛丽卡
- Codevs 1021 玛丽卡
- Codevs 1021 玛丽卡
- codevs 1021 玛丽卡
- 【codevs 1021】玛丽卡
- 【codevs 1021】玛丽卡
- codevs 1021 玛丽卡
- codevs 1021 玛丽卡
- CODEVS 1021 玛丽卡
- Codevs 1021 玛丽卡
- 16.1114 模拟考试T1
- LIBSVM的SMO算法(update alpha)
- oracle找不到sid的问题解决
- java设计模式--组合模式
- [Python模块学习]用imghdr模块识别图片格式
- Codevs 1021 玛丽卡==洛谷 P1186
- N级架构演化史
- NOIP 前夕 模板整理
- 16.1116 NOIP 考前模拟(信心题)
- Codevs 1215 迷宫
- Map集合的功能概述
- 16.1117 NOIP 模拟赛
- 最长公共上升子序列
- dom03节点的插入移除克隆