bzoj 4398 福慧双修 题解
来源:互联网 发布:90后女保镖走红网络 编辑:程序博客网 时间:2024/04/29 18:38
卡了一晚上啊
首先我们要跑一边整张图的spfa,记录每个点是从哪条边出去的(pre数组)
这里记录的不是前驱边,而是和原点相连的第一个点编号,因为不能走重复边所以才要记录这个,以免刚刚出去又原路返回
那么有一个朴素思路:spfa每一个1点连出去的点
事实上这样是会T的。。。
从这里改进,我们发现上面那种方法走了很多重复的工作,每一次spfa其实是非常类似的
那么我们可以优化一下这个过程:建一张新图跑spfa
这张新图这样建:建立新汇点n+1,设当前边(u,v,w)
1.原点连出的{
pre[v]!=v的话,连1,v,w
否则不连
}
2.连向原点的{
pre[u]!=u 直接用dis[u]+w更新答案
否则连u,n+1,w
}
3.其他的,如果pre[u]==pre[v]从一到v建dis[u]+w的边
否则保留原边
那么新图的最短路就是答案
某个T掉了的
//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 1000000000using 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];void addedge(int x,int y,int z){size++;edge[size].to=y;edge[size].next=first[x];first[x]=size;edge[size].len=z;}int head,tail;int spfa(int now,int lim){head=0,tail=1;memset(dis,63,sizeof dis);dis[now]=0,dl[1]=now;while(head!=tail){inc(head);int v=dl[head];exsit[v]=false;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);addedge(s,e,l);addedge(e,s,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 1000000000using 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;void addedge(int x,int y,int z){size++;edge[size].to=y;edge[size].next=first[x];first[x]=size;edge[size].len=z;edge[size].from=x;}void add(int x,int y,int z){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);}int head,tail,ans=inf;void spfa(){while(head!=tail){inc(head);int v=dl[head];exsit[v]=false;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);head=0,tail=1;dis[1]=0;dl[1]=1;while(head!=tail){inc(head);int v=dl[head];exsit[v]=false;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);}else addedge(s,e,l),addedge(e,s,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]){add(edge[i].from,n+1,edge[i].len);}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){add(1,edge[i].to,edge[i].len);}}else{if(pre[edge[i].from]==pre[edge[i].to]){add(edge[i].from,edge[i].to,edge[i].len);}else{add(1,edge[i].to,dis[edge[i].from]+edge[i].len);}}}cout<<Spfa()<<endl;}
0 0
- bzoj 4398 福慧双修 题解
- BZOJ 2407: 探险/BZOJ 4398: 福慧双修 dijkstra 构造
- bzoj题解
- bzoj 1218题解
- bzoj 2456 mode 题解
- bzoj 2506 calc 题解
- BZOJ 1257 (题解)
- bzoj 1003 题解
- bzoj 1053 题解
- bzoj 2761 题解
- bzoj 2464 题解
- bzoj 1085 题解
- bzoj 2464 题解
- bzoj 1045 题解
- bzoj 1059 题解
- bzoj 1054 题解
- bzoj 1050 题解
- bzoj 1047 题解
- 用户空间的open()是怎么调用到file_operations中提供的open函数的
- 【杭电oj】2719 - The Seven Percent Solution (特殊字符输出)(水)
- KMP算法详解
- 11 是否存在子树 & 二叉树镜像
- xcode7真机调试identifier not avaliable错误
- bzoj 4398 福慧双修 题解
- 寻找出现最多的数(超过一半)
- Android - AutoCompleteTextView (输入框动态匹配内容)
- AndroidStudio使用教程(第七弹)
- App应用分享__柠檬App记录器(LemonAppRecorder)
- 汉字统计
- LaTeX编译出现错误?
- Spring MVC 映射处理器配置
- python 中异常处理方式