0x61 最短路
终于会dij了原来我以前写的也是堆优化spfa-_-!
poj3662DP 通过spfa来放缩(可怜我去年NOIP的day1t3啊)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,d,next;
}a[];int len,last[];
void ins(int x,int y,int d)
{
len++;
a[len].x=x;a[len].y=y;a[len].d=d;
a[len].next=last[x];last[x]=len;
} int list[];
int f[][];bool v[];
int main()
{
int n,m,K,x,y,d;
scanf("%d%d%d",&n,&m,&K);
len=;memset(last,,sizeof(last));
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&d);
ins(x,y,d);ins(y,x,d);
} int head=,tail=;list[]=;
memset(f,,sizeof(f));f[][]=;
memset(v,false,sizeof(v));v[]=true;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
for(int p=;p<=K;p++)
{
int tt=f[y][p];
if(p!=)f[y][p]=min(f[y][p],f[x][p-]);
f[y][p]=min(f[y][p],max(f[x][p],a[k].d)); if(tt!=f[y][p]&&v[y]==false)
{
v[y]=true;
list[tail]=y;
tail++;if(tail==)tail=;
}
}
}
v[x]=false;
head++;if(head==)head=;
}
if(f[n][K]==f[][])printf("-1\n");
else printf("%d\n",f[n][K]);
return ;
}
poj3662
最优贸易 正反dij分别求最小和最大,然后mx[x]-mn[x]就好(怎么这个专题净勾起我的伤心事啊,初一的某模拟赛就是没还原v数组100变没分啊啊啊)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std; struct node{int x,y,next;}a[],e[];
int alen,elen,alast[],elast[];
void ains(int x,int y)
{
alen++;
a[alen].x=x;a[alen].y=y;
a[alen].next=alast[x];alast[x]=alen;
}
void eins(int x,int y)
{
elen++;
e[elen].x=x;e[elen].y=y;
e[elen].next=elast[x];elast[x]=elen;
} struct dij
{
int k,id;
dij(){}
dij(int K,int ID){k=K;id=ID;}
friend bool operator>(dij d1,dij d2){return d1.k>d2.k;}
friend bool operator<(dij d1,dij d2){return d1.k<d2.k;}
};
priority_queue<dij,vector<dij>,greater<dij> >aq;
priority_queue<dij>eq;
int mn[],mx[];bool v[],inq[]; int w[];
int main()
{
int n,m,x,y,op;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&w[i]);
alen=;memset(alast,,sizeof(alast));
elen=;memset(elast,,sizeof(elast));
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&op);
if(op==)
ains(x,y), eins(y,x);
else
ains(x,y),ains(y,x), eins(x,y),eins(y,x);
} memset(v,false,sizeof(v));
memset(inq,false,sizeof(inq));inq[]=true;
mn[]=w[]; aq.push(dij(w[],));
while(!aq.empty())
{
dij tno=aq.top();aq.pop();
if(v[tno.id]==true)continue;
v[tno.id]=true; int x=tno.id;
for(int k=alast[x];k;k=a[k].next)
{
int y=a[k].y;
if(inq[y]==false)
inq[y]=true, mn[y]=w[y], aq.push(dij(mn[y],y));
if(mn[y]>tno.k)
{
mn[y]=tno.k;
aq.push(dij(mn[y],y));
}
}
} memset(v,false,sizeof(v));
memset(inq,false,sizeof(inq));inq[]=true;
mx[n]=w[n], eq.push(dij(w[n],n));
while(!eq.empty())
{
dij tno=eq.top();eq.pop();
if(v[tno.id]==true)continue;
v[tno.id]=true; int x=tno.id;
for(int k=elast[x];k;k=e[k].next)
{
int y=e[k].y;
if(inq[y]==false)
inq[y]=true, mx[y]=w[y], eq.push(dij(mx[y],y));
if(mx[y]<tno.k)
{
mx[y]=tno.k;
eq.push(dij(mx[y],y));
}
}
} int ans=;
for(int i=;i<=n;i++)
ans=max(ans,mx[i]-mn[i]);
printf("%d\n",ans);
/*
for(int i=1;i<=n;i++)printf("%d ",mx[i]);
printf("\n");
for(int i=1;i<=n;i++)printf("%d ",mn[i]);
printf("\n");*/
return ;
}
最优贸易
bzoj2200 这题卡spfa(然而用酸辣粉和啦(fan)啦(you)啦(hua)这两个玄学优化可以过)
正解呢是topsort+dij,因为把正边看成联通块,负边其实构成的是一个DAG图,所以拓扑排序时顺便把环dij一次
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std; struct node
{
int x,y,d,next;
}a[];int len,last[];
void ins(int x,int y,int d)
{
len++;
a[len].x=x;a[len].y=y;a[len].d=d;
a[len].next=last[x];last[x]=len;
}
int fa[];
int findfa(int x)
{
if(fa[x]==x)return x;
fa[x]=findfa(fa[x]);return fa[x];
} int d[];
struct dij
{
int k,id;
dij(){}
dij(int K,int ID){k=K;id=ID;}
friend bool operator>(dij d1,dij d2){return d1.k>d2.k;}
friend bool operator<(dij d1,dij d2){return d1.k<d2.k;}
}; bool v[];
priority_queue<dij,vector<dij>,greater<dij> >q;
void dijkstra(int st,int k)
{
if(d[st]<=k)return ;
d[st]=k;q.push(dij(d[st],st));
memset(v,false,sizeof(v));
while(!q.empty())
{
dij tno=q.top();q.pop();
if(v[tno.id]==true)continue;
v[tno.id]=true; int x=tno.id;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(d[y]>d[x]+a[k].d)
{
d[y]=d[x]+a[k].d;
q.push(dij(d[y],y));
}
}
}
} //----------------合并成联通块+dijkstra处理正环--------------------- struct enode
{
int fx,fy,x,y,d,next;
}e[];int elen,elast[];
void eins(int fx,int fy,int x,int y,int d)
{
elen++;
e[elen].fx=fx;e[elen].fy=fy;
e[elen].x=x;e[elen].y=y;e[elen].d=d;
e[elen].next=elast[fx];elast[fx]=elen;
}
int du[],n,S;
int top,sta[];
void topsort()
{
top=;sta[++top]=;
eins(,findfa(S),,S,),du[findfa(S)]++;
for(int i=;i<=n;i++)
if(findfa(i)==i&&du[i]==&&i!=findfa(S))
sta[++top]=i;
while(top!=)
{
int fx=sta[top];top--;
for(int k=elast[fx];k;k=e[k].next)
{
du[e[k].fy]--;
if(du[e[k].fy]==)sta[++top]=e[k].fy;
}
}
while(top!=)
{
int fx=sta[top];top--;
for(int k=elast[fx];k;k=e[k].next)
{
dijkstra(e[k].y,d[e[k].x]+e[k].d);
du[e[k].fy]--;
if(du[e[k].fy]==)sta[++top]=e[k].fy;
}
}
} //--------------topsort-------------------- int main()
{
int R,P,x,y,dd;
scanf("%d%d%d%d",&n,&R,&P,&S);
len=;memset(last,,sizeof(last));
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=R;i++)
{
scanf("%d%d%d",&x,&y,&dd);
ins(x,y,dd);ins(y,x,dd); int fx=findfa(x),fy=findfa(y);
fa[fx]=fy;
} memset(du,,sizeof(du));
for(int i=;i<=P;i++)
{
scanf("%d%d%d",&x,&y,&dd);
int fx=findfa(x),fy=findfa(y);
eins(fx,fy,x,y,dd);
du[fy]++;
}
memset(d,,sizeof(d));d[]=;
topsort(); for(int i=;i<=n;i++)
if(d[i]==d[n+])printf("NO PATH\n");
else printf("%d\n",d[i]);
return ;
}
bzoj2200
poj1734 floyd求最小环,考虑对于一个环,把它拆分成前k-1个点和第k个点,当floyd完k-1次,得到的就是利用前k-1个点相互到达的最短路,此时再加上第k个点构成环,保证不重复,同时,取最大的点和取其他点,效果是一样的。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int a[][],mp[][];
int len,as[],pos[][];
void getpath(int i,int j)
{
if(pos[i][j]==)return ;
getpath(i,pos[i][j]);
as[++len]=pos[i][j];
getpath(pos[i][j],j);
} int main()
{
freopen("TRIP.in","r",stdin);
freopen("TRIP.out","w",stdout);
int n,m,x,y,d;
scanf("%d%d",&n,&m);
memset(mp,,sizeof(mp));
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&d);
mp[x][y]=min(mp[x][y],d);
mp[y][x]=min(mp[y][x],d);
}
memcpy(a,mp,sizeof(mp)); int ans=mp[][];
memset(pos,,sizeof(pos));
for(int k=;k<=n;k++)
{
for(int i=;i<k;i++)
for(int j=i+;j<k;j++)
{
if((long long)mp[i][j]+a[i][k]+a[k][j]<ans)
{
ans=mp[i][j]+a[i][k]+a[k][j];
len=;
as[++len]=i;
getpath(i,j);
as[++len]=j;
as[++len]=k;
}
} for(int i=;i<=n;i++) if(i!=k)
for(int j=;j<=n;j++) if(j!=k&&j!=i)
if(mp[i][j]>mp[i][k]+mp[k][j])
{
mp[i][j]=mp[i][k]+mp[k][j];
pos[i][j]=k;
}
}
if(ans==mp[][])printf("No solution.\n");
else
{
for(int i=;i<len;i++)printf("%d ",as[i]);
printf("%d\n",as[len]);
} return ;
}
poj1734
poj3613 神仙题
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct line{int d,x,y;}li[];
int n,ls[];
struct Matrix{int mp[][];}A,ans;
Matrix calc(Matrix a,Matrix b)
{
Matrix c;
memset(c.mp,,sizeof(c.mp));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
for(int k=;k<=n;k++)
c.mp[i][j]=min(c.mp[i][j],a.mp[i][k]+b.mp[k][j]);
return c;
}
int main()
{
int m,P,S,E;
scanf("%d%d%d%d",&P,&m,&S,&E);
n=;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&li[i].d,&li[i].x,&li[i].y);
ls[++n]=li[i].x;
ls[++n]=li[i].y;
}
sort(ls+,ls+n+);
n=unique(ls+,ls+n+)-ls-;
for(int i=;i<=m;i++)
{
li[i].x=lower_bound(ls+,ls+n+,li[i].x)-ls;
li[i].y=lower_bound(ls+,ls+n+,li[i].y)-ls;
}
S=lower_bound(ls+,ls+n+,S)-ls;
E=lower_bound(ls+,ls+n+,E)-ls;
//LSH memset(A.mp,,sizeof(A.mp));
for(int i=;i<=m;i++)
{
int x=li[i].x,y=li[i].y;
A.mp[x][y]=min(A.mp[x][y],li[i].d);
A.mp[y][x]=min(A.mp[y][x],li[i].d);
}
memcpy(ans.mp,A.mp,sizeof(A.mp));
P--;
while(P!=)
{
if(P%==)ans=calc(ans,A);
A=calc(A,A);P/=;
}
printf("%d\n",ans.mp[S][E]);
return ;
}
poj3613
0x61 最短路的更多相关文章
- bzoj1001--最大流转最短路
http://www.lydsy.com/JudgeOnline/problem.php?id=1001 思路:这应该算是经典的最大流求最小割吧.不过题目中n,m<=1000,用最大流会TLE, ...
- 【USACO 3.2】Sweet Butter(最短路)
题意 一个联通图里给定若干个点,求他们到某点距离之和的最小值. 题解 枚举到的某点,然后优先队列优化的dijkstra求最短路,把给定的点到其的最短路加起来,更新最小值.复杂度是\(O(NElogE) ...
- Sicily 1031: Campus (最短路)
这是一道典型的最短路问题,直接用Dijkstra算法便可求解,主要是需要考虑输入的点是不是在已给出的地图中,具体看代码 #include<bits/stdc++.h> #define MA ...
- 最短路(Floyd)
关于最短的先记下了 Floyd算法: 1.比较精简准确的关于Floyd思想的表达:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B.所以,我们假设maz ...
- bzoj1266最短路+最小割
本来写了spfa wa了 看到网上有人写Floyd过了 表示不开心 ̄へ ̄ 改成Floyd试试... 还是wa ヾ(。`Д´。)原来是建图错了(样例怎么过的) 结果T了 于是把Floyd改回spfa 还 ...
- HDU2433 BFS最短路
Travel Time Limit: 10000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- 最短路(代码来源于kuangbin和百度)
最短路 最短路有多种算法,常见的有一下几种:Dijstra.Floyd.Bellman-Ford,其中Dijstra和Bellman-Ford还有优化:Dijstra可以用优先队列(或者堆)优化,Be ...
- Javascript优化细节:短路表达式
什么是短路表达式? 短路表达式:作为"&&"和"||"操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程 ...
- Python中三目计算符的正确用法及短路逻辑
今天在看别人代码时看到这样一种写法, 感觉是个挺容易踩到的坑, 搞清楚后写出来备忘. 短路逻辑 Python中进行逻辑运算的时候, 默认采用的是一种叫做短路逻辑的运算规则. 名字是很形象的, 下面直接 ...
随机推荐
- C#将文件压缩成一个文件流,供前端下载
直接上代码供大家参考... 前端页面就是一个下载的Button.. <body> <form id="form1" runat="server" ...
- JavaScript异步加载方案
(1) defer,只支持IE defer属性的定义和用法(我摘自w3school网站) defer 属性规定是否对脚本执行进行延迟,直到页面加载为止. 有的 javascript 脚本 docume ...
- Android学习——动态注册监听网络变化
新建一个BroadcastTest项目,然后修改MainActivity中的代码,如下: public class MainActivity extends AppCompatActivity { p ...
- 手动触发dom节点事件代码
在爬代码过程中,碰到一个稀奇古怪的问题.需要手工修改select的值,然后手动触发select的change事件,但使用网络上查到的通过trigger.onchange()事件触发都不执行,没办法,只 ...
- EKF优化:协方差coff计算公式、意义、Code优化
复习!复习! 原文链接:http://blog.csdn.net/goodshot/article/details/8611178 1.代码: Matlab相关系数的意义: Eigen::Matrix ...
- html中的小知识
引用外部样式 样式表,如果是引用外部样式,不需要再写style标签了,因为 <link rel="stylesheet" type="text/css" ...
- (转)C#开发微信门户及应用(4)--关注用户列表及详细信息管理
http://www.cnblogs.com/wuhuacong/p/3695213.html 在上个月的对C#开发微信门户及应用做了介绍,写过了几篇的随笔进行分享,由于时间关系,间隔了一段时间没有继 ...
- Apex语言(六)数组
1.数组 数组能保存多个数据,每一个数据称为数组元素,元素的个数称为数组的长度. 数组元素的类型必须相同,元素的类型就是数组的类型. 数组元素在数组中都有一个编号,称为数组下标.下标从0开始编号,通过 ...
- lvs直接路由模式DR模式
1)实验所有关闭防火墙systemtcl stop firewalldsystemctl disable firewalldsetenforce 0iptables -F2)配置负载调度器配置虚拟IP ...
- ListUtil集合操作常用方法类
* 集合操作常用方法类. * <p> * * @author 柯 */ public class ListUtil { /** * 判断List不为空,非空返回true,空则返回false ...