Luogu P2149 [SDOI2009]Elaxia的路線
阿新 • • 發佈:2019-02-01
一看是purple題很慫。。。我太弱了。。。
但是在這個塊裡面得再刷一題,
另兩題一題是差分,一題是網路流(還是我並不知道是什麼的最小割。。。)
出於lazy的原因並不想學習差分和最小割(並學不會)
又回到了此題,認真看了一遍,
覺得SPFA再列舉兩個最短路中的所有邊看公共邊就好了吧。。。
可是如果有不同的最短路呢,如果有特別多不同的最短路呢
那。。。該怎麼實現呢 那。。。我就不會了啊
又繼續想,從模擬樣例開始,我覺得最短路中的公共路應該連在一起吧,開頭一條邊,中間兩條邊是不會有的
這樣又怎麼樣呢,怎麼樣呢。。。
give up–>看題解
公共路還真是連在一起的!
SPFA沒錯,然後的做法有拓撲和dp等等
我選擇開始打最友善(只看得懂)
spfa*4 —>對最短路上的邊再建圖—>建完圖找最長鏈
並且認識到了一種判斷邊是否在最短路上的方法
如果st到x的距離+x,y之間距離+y到ed之間距離 那麼x->y這條邊在最短路上
#include<cstdio>
#include<cstring>
int n,m,s1,e1,s2,e2,len,lenn,ans=0;
struct nod1{int x,y,c,next;}a[1000100],a2[1000100];
//。。。試了好幾次才開對了空間,空間還是算不準。。。
int first[3100],ffirst[3100],max[3100 ],b[3100];
int road1[3100],road2[3100],road3[3100],road4[3100];
int ins(int x,int y,int c)
{//第一次建圖 spfa)
len++;
a[len].x=x;
a[len].y=y;
a[len].c=c;
a[len].next=first[x];
first[x]=len;
}
int inss(int x,int y,int c)
{//第二次建圖 搜尋)
lenn++;
a2[lenn].x=x;
a2[lenn].y=y;
a2[lenn].c=c;
a2[lenn].next=ffirst[x];
ffirst[x]=lenn;
}
int spfa(int st,int *road)
{
int tou=1,wei=2;
int f[10010];
f[tou]=st;
road[st]=0;
memset(b,0,sizeof(b));
b[st]=1;
while(tou<wei)
{
int x=f[tou];
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(road[y]>road[x]+a[i].c)
{
road[y]=road[x]+a[i].c;
if(b[y]==0)
{
b[y]=1;
f[wei]=y;
wei++;
}
}
}
b[x]=0;
tou++;
}
}
int find(int x)
{//搜尋找最長鏈
if(max[x]!=0)return max[x];
for(int i=ffirst[x];i;i=a2[i].next)
{
int y=a2[i].y,z=a2[i].c;
if(find(y)+z>max[x])
{
max[x]=max[y]+z;
}
}
return max[x];
}
int buildpic()
{
for(int i=1;i<=len;i++)
{
int x=a[i].x,y=a[i].y,z=a[i].c;
if(((road1[x]+z+road2[y]==road1[e1])&&(road3[x]+z+road4[y]==road3[e2]))
||((road1[y]+z+road2[x]==road1[e1])&&(road3[x]+z+road4[y]==road3[e2])))
{
inss(x,y,z);//printf("!!!!! ");
}
}
}
int main()
{
scanf("%d %d",&n,&m);
scanf("%d %d %d %d",&s1,&e1,&s2,&e2);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
ins(x,y,z);ins(y,x,z);
}
memset(road1,63,sizeof(road1));
memset(road2,63,sizeof(road2));
memset(road3,63,sizeof(road3));
memset(road4,63,sizeof(road4));
//4*spfa
spfa(s1,road1);
spfa(e1,road2);
spfa(s2,road3);
spfa(e2,road4);
//printf("%d %d ",road1[e1],road3[e2]);
buildpic();//建圖
for(int i=1;i<=n;i++)
{
if(max[i]==0)
{
//printf("11111111");
find(i);
//printf("222222222");
}//printf("1111");
if(max[i]>ans)ans=max[i];
}
printf("%d",ans);
}
在RE了3次後終於A了 這個塊終於過la 以後要注意空間