您的位置:首页 > 其它

BZOJ 2200: [Usaco2011 Jan]道路和航线

2016-10-28 16:54 381 查看
这道题嘛 其实好像直接上spfa就好了 不过他有意想卡你一下

不过我加了一个优化就过了(原来spfa有优化。。SLF就好 LLL好像不常用)

dijkstra的做法的确快很多 不过也麻烦的多了(不过应该是思维性所在吧)

不难发现 根据题意 因为不存在走回来的情况 负边连接的都是两个连通块

所以分开来对每个连通块内做dijkstra 然后外面对于连通块用拓扑序来搞 搞连通块的时候把外面进来的扔进队列就好。。细节很多

想想就觉得热爱学习也是蛋疼打了两种做法 第二种真是烦。。要注意细节啊。。

是不是应该夸我(手动笑cry)

spfa:

#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define me(a,x) memset(a,x,sizeof a)
#define cp(a,x) memcpy(a,x,sizeof a)
using namespace std;
const int N=25010,inf=1e9;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
struct node{int y,next,c;}a[N*6]; int len,first
;
void ins(int x,int y,int c)
{
a[++len].y=y,a[len].c=c,a[len].next=first[x],first[x]=len;
}
bool v
; int d
;
deque<int>q;
int main()
{
int i,j,x,y,c,n,m1,m2,st;
n=read(),m1=read(),m2=read(),st=read();
for(i=1;i<=m1;i++)
{
x=read(),y=read(),c=read();
ins(x,y,c),ins(y,x,c);
}
for(i=1;i<=m2;i++)
x=read(),y=read(),c=read(),ins(x,y,c);
q.push_front(st); me(d,63);
int s=0,l=1; d[st]=0,v[st]=1;
while(!q.empty())
{
x=q.front();
q.pop_front(); v[x]=0;
for(int k=first[x];k;k=a[k].next)
{
y=a[k].y;
if(d[y]>d[x]+a[k].c)
{
d[y]=d[x]+a[k].c;
if(v[y])continue;
v[y]=1;
if(!q.empty())
{
if(d[y]<d[q.front()])q.push_front(y);
else q.push_back(y);
}
else q.push_back(y);
}
}
}
for(i=1;i<=n;i++)
if(d[i]>inf)printf("NO PATH\n");
else printf("%d\n",d[i]);
return 0;
}


dijkstra:

#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define me(a,x) memset(a,x,sizeof a)
#define cp(a,x) memcpy(a,x,sizeof a)
using namespace std;
typedef long long LL;
const int N=25010,inf=1e9;
inline int read()
{
LL x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
struct node{int x,y,next,c;}a[N*6]; int len,first
;
void ins(int x,int y,int c)
{
a[++len].y=y,a[len].c=c,a[len].next=first[x],first[x]=len;
}
struct P{
int x,y;
bool operator <(const P &t) const
{
return y>t.y;
}
};
bool v
; int d
,fa
,p
,l,r
;
priority_queue<P>q;
vector<int>u
,J
;
queue<int>Q;
int fi(int x){return fa[x]==x?x:fa[x]=fi(fa[x]);}
int main()
{
int i,j,x,y,c,n,m1,m2,st;
n=read(),m1=read(),m2=read(),st=read();
for(i=1;i<=n;i++)fa[i]=i;
for(i=1;i<=m1;i++)
{
x=read(),y=read(),c=read();
ins(x,y,c),ins(y,x,c),fa[fi(x)]=fi(y);
}
l=0; for(i=1;i<=n;i++)if(fa[i]==i)p[i]=++l;
for(i=1;i<=n;i++)fa[i]=fi(fa[i]);
for(i=1;i<=m2;i++)
{
x=read(),y=read(),c=read();
a[len+i].x=x,a[len+i].y=y,a[len+i].c=c;
u[p[fa[x]]].push_back(i+len),r[p[fa[y]]]++;
J[p[fa[y]]].push_back(y);
}
for(i=1;i<=l;i++) if(!r[i])Q.push(i);
for(i=1;i<=n;i++) if(fa[i]==i&&r[p[i]]==0) J[p[i]].push_back(i);
me(d,63); d[st]=0; J[p[fa[st]]].push_back(st);
while(!Q.empty())
{
int now=Q.front(); Q.pop();
for(i=0;i<J[now].size();i++)
{
int U=J[now][i];
q.push( (P){d[U],U} );
}
while(!q.empty())
{
P g=q.top(); q.pop();
if(d[g.y]<g.x)continue;
for(i=first[g.y];i;i=a[i].next)
{
y=a[i].y;
if(d[y]>d[g.y]+a[i].c)
{
d[y]=d[g.y]+a[i].c;
q.push( (P){d[y],y} );
}
}
}
for(i=0;i<u[now].size();i++)
{
j=u[now][i]; r[p[fa[a[j].y]]]--;
if(!r[p[fa[a[j].y]]]) Q.push(p[fa[a[j].y]]);
d[a[j].y]=min(d[a[j].y],d[a[j].x]+a[j].c);
}
}
for(i=1;i<=n;i++)
if(d[i]<inf)printf("%d\n",d[i]);
else printf("NO PATH\n");
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: