# bzoj 4398 福慧双修 题解

1.原点连出的{

pre[v]!=v的话，连1,v,w

}

2.连向原点的{

pre[u]!=u 直接用dis[u]+w更新答案

}

3.其他的，如果pre[u]==pre[v]从一到v建dis[u]+w的边

//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define o(e) ((((e)-1)^1)+1)
#define inc(a) a++;if(a==100000)a=1;
#define inf 1000000000
using namespace std;
inline void splay(int &v){
v=0;char c=0;int p=1;
while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
v*=p;
}
struct Edge{
int to,next,len;
}edge[200010];
int first[100010],size;
int dis[40010],dl[100010];
bool exsit[40010];
size++;
edge[size].to=y;
edge[size].next=first[x];
first[x]=size;
edge[size].len=z;
}
int spfa(int now,int lim){
memset(dis,63,sizeof dis);
dis[now]=0,dl[1]=now;
for(int u=first[v];u;u=edge[u].next){
if(edge[u].len+dis[v]<dis[edge[u].to] && u!=lim){
dis[edge[u].to]=edge[u].len+dis[v];
if(!exsit[edge[u].to]){
exsit[edge[u].to]=true;
inc(tail);dl[tail]=edge[u].to;
}
}
}
}
return dis[1];
}
int main(){
freopen("xxx.in","r",stdin);
freopen("xxx.out","w",stdout);
int n,m;splay(n),splay(m);
for(int i=1;i<=m;i++){
int s,e,l,r;
splay(s),splay(e),splay(l),splay(r);
}
int ans=inf;
for(int u=first[1];u;u=edge[u].next){
ans=min(ans,spfa(edge[u].to,o(u))+edge[u].len);
}
cout<<ans<<endl;
}
A了的

//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define o(e) ((((e)-1)^1)+1)
#define inc(a) a++;if(a==100000)a=1;
#define inf 1000000000
using namespace std;
inline void splay(int &v){
v=0;char c=0;int p=1;
while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
v*=p;
}
struct Edge{
int to,next,len,from;
}edge[300010],e[300010];
int first[100010],size;
int dis[40010],dl[100010];
bool exsit[40010];
int pre[40010];
int f[40010],s;
int n,m;
size++;
edge[size].to=y;
edge[size].next=first[x];
first[x]=size;
edge[size].len=z;
edge[size].from=x;
}
s++;
e[s].to=y;
e[s].next=f[x];
f[x]=s;
e[s].len=z;
fprintf(stderr,"%d %d %d\n",x,y,z);
}
void spfa(){
for(int u=first[v];u;u=edge[u].next){
if(edge[u].len+dis[v]<dis[edge[u].to]){
dis[edge[u].to]=edge[u].len+dis[v];
pre[edge[u].to]=pre[v];
if(!exsit[edge[u].to]){
exsit[edge[u].to]=true;
inc(tail);dl[tail]=edge[u].to;
}
}
}
}
}
int Spfa(){
memset(dis,63,sizeof dis);
for(int u=f[v];u;u=e[u].next){
if(e[u].len+dis[v]<dis[e[u].to]){
dis[e[u].to]=e[u].len+dis[v];
if(!exsit[e[u].to]){
exsit[e[u].to]=true;
inc(tail);dl[tail]=e[u].to;
}
}
}
}
return dis[n+1];
}
int main(){
freopen("xxx.in","r",stdin);
freopen("xxx.out","w",stdout);
splay(n),splay(m);
for(int i=1;i<=m;i++){
int s,e,l,r;
splay(s),splay(e),splay(l),splay(r);
if(s==e&&s==1){
ans=min(ans,l),ans=min(ans,r);
}
}
memset(dis,63,sizeof dis);
for(int u=first[1];u;u=edge[u].next){
dl[++tail]=edge[u].to;
exsit[edge[u].to]=true;
pre[edge[u].to]=edge[u].to;
dis[edge[u].to]=edge[u].len;
}
spfa();
for(int i=1;i<=size;i++){
if(edge[i].to==1){
if(edge[i].from==pre[edge[i].from]){
}
else{
ans=min(ans,dis[edge[i].from]+edge[i].len);
}
}
else if(edge[i].from==1){
if(pre[edge[i].to]!=edge[i].to){
}
}
else{
if(pre[edge[i].from]==pre[edge[i].to]){
}
else{
}
}

}
cout<<Spfa()<<endl;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120