P2149 [SDOI2009]Elaxia的路线

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2149 [SDOI2009]Elaxia的路线相关的知识,希望对你有一定的参考价值。

题目描述

最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间。Elaxia和w每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。 现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

输入输出格式

输入格式:

第一行:两个整数N和M(含义如题目描述)。 第二行:四个整数x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ ≤ N),分别表示Elaxia的宿舍和实验室及w**的宿舍和实验室的标号(两对点分别 x1,y1和x2,y2)。 接下来M行:每行三个整数,u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之间有一条路,经过这条路所需要的时间为l。

输出格式:

一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)

输入输出样例

输入样例#1:
9 10
1 6 7 8
1 2 1
2 5 2
2 3 3
3 4 2
3 9 5
4 5 3
4 6 4
4 7 2
5 8 1
7 9 1
输出样例#1:
3

说明

对于30%的数据,N ≤ 100;

对于60%的数据,N ≤ 1000;

对于100%的数据,N ≤ 1500,输入数据保证没有重边和自环。

 

首先跑四遍SPFA求出各个点之间的最短路

然后暴力枚举每一个点,跑出一个新的图

再在图上跑拓扑

找出最大值

 

技术分享
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<queue>
  6 using namespace std;
  7 const int MAXN=200001;
  8 int n,m;
  9 int x11,y11,x22,y22;
 10 struct node
 11 {
 12     int u,v,w,next;
 13 }edge[MAXN],newedge[MAXN];
 14 int num=1;
 15 int head[MAXN];
 16 int newnum=1;
 17 int newhead[MAXN];
 18 int dis[5][MAXN];
 19 int vis[MAXN];
 20 int ans=0;
 21 int rudu[MAXN];
 22 void SPFA(int k,int now)
 23 {
 24     queue<int>q;
 25     memset(vis,0,sizeof(vis));
 26     memset(dis[now],0x7f,sizeof(dis[now]));
 27     q.push(k);vis[k]=1;dis[now][k]=0;
 28     while(q.size()!=0)
 29     {
 30         int p=q.front();q.pop();
 31         for(int i=head[p];i!=-1;i=edge[i].next)
 32         {
 33             int where=edge[i].u;
 34             int to=edge[i].v;
 35             if(dis[now][to]>dis[now][p]+edge[i].w)
 36             {
 37                 dis[now][to]=dis[now][p]+edge[i].w;
 38                 if(vis[to]==0)
 39                 {vis[to]=1;q.push(to);}
 40             }
 41         }
 42     }
 43     /*for(int i=1;i<=n;i++)
 44         cout<<dis[now][i]<<" ";
 45     cout<<endl;*/
 46 }
 47 void topsort()
 48 {
 49     int dis[MAXN];
 50     memset(dis,0,sizeof(dis));
 51     queue<int>q;
 52     for(int i=1;i<=n;i++)
 53         if(rudu[i]==0)
 54             q.push(i);
 55     while(q.size()!=0)
 56     {
 57         int p=q.front();q.pop();
 58         ans=max(ans,dis[p]);
 59         for(int i=head[p];i!=-1;i=edge[i].next)
 60         {
 61             dis[newedge[i].v]=max(dis[newedge[i].v],dis[p]+newedge[i].w);
 62             rudu[newedge[i].v]--;
 63             if(rudu[newedge[i].v]==0)
 64             q.push(newedge[i].v);
 65         }
 66     }
 67 }
 68 void build()
 69 {
 70     for(int i=1;i<=n;i++)
 71         for(int j=head[i];j!=-1;j=edge[j].next)
 72         {
 73             int where=edge[j].u;int to=edge[j].v;
 74             if(dis[1][i]+edge[j].w+dis[2][to]==dis[1][y11]&&dis[3][i]+edge[j].w+dis[4][to]==dis[3][y22])
 75             {
 76                 newedge[newnum].u=edge[j].u;
 77                 newedge[newnum].v=edge[j].v;
 78                 newedge[newnum].w=edge[j].w;
 79                 newedge[newnum].next=newhead[edge[newnum].u];
 80                 rudu[newedge[newnum].v]++;
 81                 newhead[edge[newnum].u]=newnum++;
 82             }
 83         }
 84     topsort();
 85     
 86     for(int i=1;i<=n;i++)newhead[i]=-1;
 87     
 88     for(int i=1;i<=n;i++)
 89     {
 90         for(int j=head[i];j!=-1;j=edge[j].next)
 91         {
 92             int where=edge[j].u;int to=edge[j].v;
 93             if(dis[1][i]+edge[j].w+dis[2][to]==dis[1][y11]&&dis[3][to]+edge[j].w+dis[4][i]==dis[3][y22])
 94             {
 95                 newedge[newnum].u=edge[j].u;
 96                 newedge[newnum].v=edge[j].v;
 97                 newedge[newnum].w=edge[j].w;
 98                 newedge[newnum].next=newhead[edge[newnum].u];
 99                 rudu[newedge[newnum].v]++;
100                 newhead[edge[newnum].u]=newnum++;
101             }
102         }
103     }
104     topsort();
105     printf("%d",ans);
106 }
107 int main()
108 {
109     scanf("%d%d",&n,&m);
110     for(int i=1;i<=n;i++)
111     head[i]=-1,
112     newhead[i]=-1;
113     scanf("%d%d%d%d",&x11,&y11,&x22,&y22);
114     for(int i=1;i<=m;i++)
115     {
116         scanf("%d%d%d",&edge[num].u,&edge[num].v,&edge[num].w);
117         edge[num].next=head[edge[num].u];
118         head[edge[num].u]=num++;
119         edge[num].u=edge[num-1].v;
120         edge[num].v=edge[num-1].u;
121         edge[num].w=edge[num-1].w;
122         edge[num].next=head[edge[num].u];
123         head[edge[num].u]=num++;
124     }
125     SPFA(x11,1);
126     SPFA(y11,2);
127     SPFA(x22,3);
128     SPFA(y22,4);
129     build();
130     return 0;
131 }
感觉能AC但是只能过样例的代码
技术分享
 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 struct edge
 6 {
 7     int nxt,to,dis;
 8 }a[3000010];
 9 int head[10000];
10 int Head[10000];
11 int lv[10000];
12 bool b[10000];
13 int s1[10000],t1[10000],s2[10000],t2[10000];
14 int n,m,x1,y1,x2,y2,x,y,z,num,ans;
15 queue<int>q;
16 inline int max(int a,int b){return a>b?a:b;}
17 
18 inline void add(int head[],int x,int y,int z)
19 {a[++num].nxt=head[x],a[num].to=y,a[num].dis=z,head[x]=num;}
20 
21 inline void Add(int head[],int x,int y,int z){add(head,x,y,z);add(head,y,x,z);}
22 inline void SPFA(int S,int dis[])
23 {
24     memset(dis,0x3f,sizeof (int)*1510);
25     dis[S]=0;q.push(S);
26     while(!q.empty())
27     {
28         int tmp=q.front();q.pop();
29         b[tmp]=0;
30         for(int i=head[tmp];i;i=a[i].nxt)
31           if(dis[a[i].to]>dis[tmp]+a[i].dis)
32           {
33               dis[a[i].to]=dis[tmp]+a[i].dis;
34               if(!b[a[i].to]) b[a[i].to]=1,q.push(a[i].to);
35           }
36     }
37 }
38 inline void topologysort()
39 {
40     int dis[10000];
41     memset(dis,0,sizeof(dis));
42     for(int i=1;i<=n;i++)
43       if(!lv[i]) q.push(i);
44     while(!q.empty())
45     {
46         int tmp=q.front();q.pop();
47         ans=max(ans,dis[tmp]);
48         for(int i=Head[tmp];i;i=a[i].nxt)
49         {
50             dis[a[i].to]=max(dis[a[i].to],dis[tmp]+a[i].dis);
51             if(!--lv[a[i].to]) q.push(a[i].to);
52         }
53     }
54 }
55 int main()
56 {
57     scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&x2,&y2);
58     for(int i=1;i<=m;i++)
59       scanf("%d%d%d",&x,&y,&z),Add(head,x,y,z);
60     SPFA(x1,s1);SPFA(y1,t1);
61     SPFA(x2,s2);SPFA(y2,t2);
62     
63     for(int tmp=1;tmp<=n;tmp++)
64       for(int i=head[tmp];i;i=a[i].nxt)
65         if(s1[tmp]+a[i].dis+t1[a[i].to]==s1[y1]&&s2[tmp]+a[i].dis+t2[a[i].to]==s2[y2])
66           add(Head,tmp,a[i].to,a[i].dis),lv[a[i].to]++;
67     topologysort();
68     
69     memset(Head,0,sizeof(Head));
70     for(int tmp=1;tmp<=n;tmp++)
71       for(int i=head[tmp];i;i=a[i].nxt)
72         if(s1[tmp]+a[i].dis+t1[a[i].to]==s1[y1]&&s2[a[i].to]+a[i].dis+t2[tmp]==s2[y2])
73           add(Head,tmp,a[i].to,a[i].dis),lv[a[i].to]++;
74     topologysort();
75     printf("%d",ans);
76     return 0;
77 }
AC

 

以上是关于P2149 [SDOI2009]Elaxia的路线的主要内容,如果未能解决你的问题,请参考以下文章

P2149 [SDOI2009]Elaxia的路线

P2149 [SDOI2009]Elaxia的路线

洛谷—— P2149 [SDOI2009]Elaxia的路线

P2149 [SDOI2009]Elaxia的路线

P2149 [SDOI2009]Elaxia的路线[最长公共路径]

P2149 [SDOI2009]Elaxia的路线