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);
}
题解:
如果是一个值得话,那就是超水的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);
}
相关文章推荐
- BZOJ 3669 NOI2014 魔法森林 SPFA
- [BZOJ3669]-[Noi2014]魔法森林-LCT+并查集
- 【BZOJ 3669】 3669: [Noi2014]魔法森林 (动态spfa)
- [bzoj3669][NOI2014]魔法森林
- BZOJ 3669: [Noi2014]魔法森林 LCT
- 【BZOJ】【3669】【NOI2014】魔法森林
- BZOJ3669: [Noi2014]魔法森林
- BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]
- BZOJ 3669: [Noi2014]魔法森林( LCT )
- 图论 BZOJ 3669 [Noi2014]魔法森林
- bzoj3669【NOI2014】魔法森林
- 【BZOJ3669】[Noi2014]魔法森林【Link-Cut Tree】【最小生成树】
- 【BZOJ 3669】 [Noi2014]魔法森林 LCT维护动态最小生成树
- 【bzoj3669】[Noi2014]魔法森林
- bzoj 3669: [Noi2014] 魔法森林 LCT版
- BZOJ 3669: [Noi2014]魔法森林
- 【bzoj3669】[Noi2014]魔法森林
- [BZOJ3669][Noi2014]魔法森林 && LCT
- 【BZOJ3669】【NOI2014】魔法森林 LCT
- bzoj 3669: [Noi2014]魔法森林 link cut tree