您的位置:首页 > 其它

3669: [Noi2014]魔法森林

2017-09-13 21:33 169 查看
题目链接

题解:

如果是一个值得话,那就是超水的spfa,两个值的话,我们可以对spfa稍稍改变一下。

对于每个a我们排个序,那么对于每个其中一个值最大为a,直接求另外那个值最大最小就好了,

注意dis不要每次都清inf,会wa的,为什么?这明显显而易见的嘛,

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
#define inf 1e8
using namespace std;
const int N=51000;
const int M=101000;
int n,m;
struct node{
int x,y,a,b,next;
bool tf;
}sa[M*2];int len=1,first
;
struct trpe{
int id,a;
}ss[M*2];
void ins(int x,int y,int a,int b)
{
len++;
sa[len].x=x;
sa[len].y=y;
sa[len].a=a;
sa[len].b=b;
sa[len].tf=0;
sa[len].next=first[x];
first[x]=len;
}
bool cmp(trpe a,trpe b)
{
return a.a<b.a;
}
int dis
;
bool tf
;
queue<int>q;
void spfa()
{
while(!q.empty())
{
int x=q.front();q.pop();tf[x]=0;
for(int i=first[x];i!=-1;i=sa[i].next)
{
int y=sa[i].y;//printf("%d %d %d\n",x,y,i);
if(sa[i].tf&&dis[y]>max(dis[x],sa[i].b))
{

dis[y]=max(dis[x],sa[i].b);
if(!tf[y])
{
q.push(y);
tf[y]=1;
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
memset(first,-1,sizeof(first));
int x,y,a,b;
int tot=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&a,&b);
ins(x,y,a,b);ins(y,x,a,b);
ss[++tot].id=len-1;ss[tot].a=a;
}
sort(ss+1,ss+1+tot,cmp);
for(int i=1;i<=n;i++) dis[i]=inf;
bool po=false;dis[1]=0;
int ans=inf;
for(int i=1;i<=m;i++)
{
int yu=ss[i].id;
//printf("!%d %d %d\n",yu,yu+1,i);
sa[yu].tf=1;sa[yu+1].tf=1;
if(po==true||sa[yu].x==1||sa[yu].y==1)
{//printf("!!!%d %d %d %d %d\n",sa[yu].x,sa[yu].y,po,i,ss[i].a);
q.push(sa[yu].x);q.push(sa[yu].y);
memset(tf,0,sizeof(tf));
tf[sa[yu].x]=1;tf[sa[yu].y]=1;//printf("%d %d\n",ss[i].a,dis
);
po=true;spfa();ans=min(ans,ss[i].a+dis
);
}

}
if(ans==inf) printf("-1");
else
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: