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中进行逻辑运算的时候, 默认采用的是一种叫做短路逻辑的运算规则. 名字是很形象的, 下面直接 ...
随机推荐
- 5.30dao-service-controller层,mybatis自动生成。(获取根据id主键获取指定详细数据)
获取权限详细数据:(参考) 1.controller:1.注入Servcie调用方法findConsumerById(参数是id); ...
- 详细解读css中的浮动以及清除浮动的方法
对于前端初学者来说,css浮动部分的知识是一块比较难以理解的部分,下面我将把我学习过程中的心得分享给大家. 导读: 1.css块级元素讲解 2.css中浮动是如何产生的 3.出现浮动后,如何清除浮 ...
- css样式变 及实际用法
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con ...
- oracle排序union和union all区别
是这样的,表格中有几个属性,比如age吧是之一,age是字符类型的数字,select之间由union连接,此时是无法对前面的select语句进行order by的,也就是无法排序,无法达成我要的按ag ...
- HIVE 命令记录
HIVE 命令记录 设置hive运行的队列 hive> set mapreduce.job.queuename=ven12; 打印列名 hive> set hive.cli.print.h ...
- 安装rails卡住很慢 出现302 Moved Temporarily
在MAC上安装rails的时候,使用命令$ gem install rails 发现一直没响应,使用$ gem install rails-V命令发现,安装会在中间卡住,出现302 Moved Tem ...
- 【sqli-labs】 less1 GET - Error based - Single quotes - String(GET型基于错误的单引号字符型注入)
GET方式提交id参数 添加单引号,出现报错,爆出数据库名称和部分SQL语句 http://localhost/sqli/Less-1/?id=1' 使用order by猜测字段数,用#注释掉后面li ...
- 简单servlet调用dao层完整步骤
导入包lib(文件名称) 目录结构:web下:views.web-inf.index.jsp views下各种jsp文件和js(里面放封装好的jquery包) js下:jquery包(js文件后缀) ...
- 移动端调试 vConsole
<head> <script src="path/to/vconsole.min.js"></script> <script> va ...
- java8方式日期比较
static ZoneId ZONEID_BJ = ZoneId.of("GMT+08:00"); private boolean sameDate(Date d1, Date d ...