您的位置:首页 > 其它

NOI 2014 魔法森林 SPFA

2017-09-11 19:53 253 查看
在一切的故事开始之前,我要说:%%%PoPoQQQ大爷!!!ORZ



————————————————————————————————————————————————————

这个题唯一的难点就是这个边的权值有两个。。。。。

可以想到枚举一个权值,然后算另一个权值最小的路径,可以SPFA搞定。但是呢我就蒙蔽了。。。TL妥妥的怎么破ORZ

这个时候就需要PoPoQQQ大爷的帮助了:“这里要用的SPFA的动态加点(边)法 我们每加一条边 就把边的两端点入队 继续SPFA 不用对f数组进行memset”(f是我的dist)

于是问题得以解决。(但是有点小慢啊我好像是输在了系统栈上QAQ)

%%%%%%%%%%%%%%

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
#include<ctime>
#define inf 1e9
using namespace std;
const int maxn=50005;
const int maxm=100005;

int N,M;
struct edge{ int from,to,next,a,b; }E[maxm<<1],EE[maxm<<1];
int first[maxn],np,np2,dist[maxn];
bool inq[maxn];
int ans=inf;

void _scanf(int &x)
{
x=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
}
void add_edge1(int u,int v,int a,int b)
{
EE[++np]=(edge){u,v,0,a,b};
}
void add_edge2(edge e)
{
E[++np]=e;
E[np].next=first[e.from];
first[e.from]=np;
}
void data_in()
{
_scanf(N);_scanf(M);
int x,y,a,b;
for(int i=1;i<=M;i++)
{
_scanf(x);_scanf(y);_scanf(a);_scanf(b);
add_edge1(x,y,a,b);
add_edge1(y,x,a,b);
}
}
bool cmp(edge x,edge y) { return x.a<y.a; }
void SPFA()
{
sort(EE+1,EE+np+1,cmp);
M*=2,np=0;
queue<int>q;
memset(inq,0,sizeof(inq));
for(int i=1;i<=N;i++) dist[i]=inf;
dist[1]=0;
int last=EE[1].a,i=1,ii,j,now;
while(i<=M)
{
while(i<=M && EE[i].a==last)
{
add_edge2(EE[i++]);
if(!inq[E[np].from])
{
q.push(E[np].from);
inq[E[np].from]=1;
}
if(!inq[E[np].to])
{
q.push(E[np].to);
inq[E[np].to]=1;
}
}
while(!q.empty())
{
ii=q.front();q.pop();
inq[ii]=0;
for(int p=first[ii];p;p=E[p].next)
{
j=E[p].to;
now=max(dist[ii],E[p].b);
if(now<dist[j])
{
dist[j]=now;
if(!inq[j]) { q.push(j); inq[j]=1; }
}
}
}
if(last+dist
<ans) ans=last+dist
;
last=EE[i].a;
}
if(ans==inf) ans=-1;
printf("%d\n",ans);
}
int main()
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
data_in();
SPFA();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: