最近实在不知道干些什么,感觉自己除了水题什么都不会做,算了去刷一刷图论的水题吧本来想合起来一起发,想了想太长的话以后看起来也不方便,题目所以今天晚上就先发了dij部分,由上到下由易变难。

1.POJ 2387 Til the Cows Come Home(优先队列优化+邻接表)
2.poj 1502 (最短路)
3.POJ3268-Silver Cow Party-(优先队列优化+邻接表)
4.poj 1511 Invitation Cards(优先队列+dij+链向式前向星存图)
5.Heavy Transportation POJ - 1797(优先队列优化+邻接表)
6.poj2253(dij变形+优先队列)
7.hdu4725The Shortest Path in Nya Graph(建图建图建图+dij+优先队列优化)
dijk部分:
3月23日
1.POJ 2387 Til the Cows Come Home

很典型的板子题,问从1点到n点的最小花费(使用优先队列进行优化)

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn  2010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;int t,n;
bool visited[maxn];
int dis[maxn];struct wazxy{int v,val;wazxy(int v1,int e1){v=v1;val=e1;}
};
vector<wazxy> a[maxn];
struct node{int id,dis;node(int a,int b){id=a,dis=b;}bool operator < (const node & a)const{return dis>a.dis;}
};void dij(){int s=1;dis[s]=0;priority_queue<node>q;q.push(node(s,dis[s]));while(!q.empty()){node temp=q.top();q.pop();if(visited[temp.id])  continue;visited[temp.id]=true;for(int i=0;i<a[temp.id].size();i++){wazxy node1=a[temp.id][i];if(visited[node1.v]) continue;if(dis[node1.v]>node1.val+temp.dis){dis[node1.v]=node1.val+temp.dis;q.push(node(node1.v,dis[node1.v]));}}}printf("%d",dis[n]);
}int main()
{cin>>t>>n;memset(visited,false,sizeof(visited));memset(dis,MaxN,sizeof(dis));while(t--){int x,y,v;scanf("%d%d%d",&x,&y,&v);a[x].push_back(wazxy(y,v));a[y].push_back(wazxy(x,v));}dij();return 0;
}

3月24号
2.poj 1502 (最短路)

题目很坑爹:大致意思是从起点找出到每个点的最短距离,然后从到每个点的最短距离中找出一个最大值输出
找了一下午的bug,原因竟然是再一次的忘记调用dij函数md

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn  110
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
int n;
int maps[maxn][maxn];
int visited[maxn],dis[maxn];
void init(){memset(maps,MaxN,sizeof(maps));for(int i=0;i<maxn;i++) maps[i][i]=0;
}
void dij(){memset(visited,false,sizeof(visited));for(int i=1;i<=n;i++) dis[i]=maps[1][i];for(int i=1;i<=n;i++){int imin=MaxN,x;for(int f=1;f<=n;f++){if(!visited[f]&&dis[f]<=imin){x=f;imin=dis[f];}}visited[x]=true;for(int f=1;f<=n;f++){if(!visited[f]&&dis[f]>dis[x]+maps[x][f]){dis[f]=dis[x]+maps[x][f];}}}
}
int main()
{char a[10];while(scanf("%d",&n)!=EOF){init();for(int i=2;i<=n;i++){for(int j=1;j<i;j++){scanf("%s",a);if(a[0]!='x') maps[i][j]=maps[j][i]=atoi(a);}}}
//    for(int i=1;i<=n;i++){//        for(int f=1;f<=n;f++){//            cout<<maps[i][f]<<" ";
//        }
//        cout<<endl;
//    }int imax=0;dij();for(int i=1;i<=n;i++){imax=max(imax,dis[i]);
//        cout<<dis[i]<<endl;}cout<<imax<<endl;return 0;
}

3.POJ3268-Silver Cow Party-(Dijstra)
题目大意:让你求每个点到某个点x距离的最短路+x点在返回原点路径的最短路之和,找出其中和的最大值
dij+了队列优化才险些过去(735ms)

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn  1010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
struct rule{int u,v,cost;rule(int a,int b,int c){u=a,v=b,cost=c;}
};
int dis[maxn];
bool visited[maxn];
int n,m,k;
int sum[maxn];
vector <vector<rule> > a;
struct node{int n,dis;node(int a,int b){n=a,dis=b;}bool operator < (const node & a)const{return dis>a.dis;}
};
void init(){a.resize(maxn);memset(visited,false,sizeof(visited));memset(dis,MaxN,sizeof(dis));
}void dij(int x){memset(visited,false,sizeof(visited));memset(dis,MaxN,sizeof(dis));dis[x]=0;priority_queue<node> q;q.push(node(x,0));while(!q.empty()){node temp=q.top();q.pop();if(visited[temp.n]) continue;visited[temp.n]=true;for(int i=0;i<a[temp.n].size();i++){rule node1=a[temp.n][i];if(visited[node1.v]) continue;if(dis[node1.v]>node1.cost+temp.dis){dis[node1.v]=node1.cost+temp.dis;q.push(node(node1.v,dis[node1.v]));}}}
}
int main()
{cin>>n>>m>>k;init();for(int i=0;i<m;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);a[x].push_back(rule(x,y,z));}dij(k);for(int i=1;i<=n;i++) sum[i]+=dis[i];for(int i=1;i<=n;i++){dij(i);sum[i]+=dis[k];}int imax=0;for(int i=1;i<=n;i++){imax=max(imax,sum[i]);}cout<<imax<<endl;return 0;
}

3月25日:
4.poj 1511 Invitation Cards(优先队列+dij+链向式前向星存图)
其实这个题应该是昨天刷完的,跟上面的题可以说是一模一样,只是数据量太大了,当然,我继续用了上一题的方法,发现超时,以为是vector的原因,换了链向式前向星存图,发现还是超时,然后就继续优化读入函数等一切可以降低复杂度的操作,发现仍然超时(心态崩了,不写了)于是查了一下题解,竟然还有反向加边这种操作,心态炸裂:
因为本人并不喜欢函数传参这种操作,所以直接用了两个dij,复制粘贴
题解:

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn  1000010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
struct rule{int v,cost,next;
}edge[maxn],edge1[maxn];
int dis[maxn];
bool visited[maxn];
int n,m,k;
ll sum;
int head[maxn];
int head1[maxn];
struct node{int n,dis;node(int a,int b){n=a,dis=b;}bool operator < (const node & a)const{return dis>a.dis;}
};
int cnt=0,cnt1;
inline void add(int u,int v,int w){edge[cnt].cost=w;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;
}
inline void add1(int u,int v,int w){edge1[cnt1].cost=w;edge1[cnt1].v=v;edge1[cnt1].next=head1[u];head1[u]=cnt1++;
}
inline void dij(int x){memset(visited,false,sizeof(visited));memset(dis,MaxN,sizeof(dis));dis[x]=0;priority_queue<node> q;q.push(node(x,0));while(!q.empty()){node temp=q.top();q.pop();if(visited[temp.n]) continue;visited[temp.n]=true;for(int i=head[temp.n];i!=-1;i=edge[i].next){int v=edge[i].v;if(visited[v]) continue;if(dis[v]>temp.dis+edge[i].cost){dis[v]=temp.dis+edge[i].cost;q.push(node(v,dis[v]));}}}
}
inline void dij1(int x){memset(visited,false,sizeof(visited));memset(dis,MaxN,sizeof(dis));dis[x]=0;priority_queue<node> q;q.push(node(x,0));while(!q.empty()){node temp=q.top();q.pop();if(visited[temp.n]) continue;visited[temp.n]=true;for(int i=head1[temp.n];i!=-1;i=edge1[i].next){int v=edge1[i].v;if(visited[v]) continue;if(dis[v]>temp.dis+edge1[i].cost){dis[v]=temp.dis+edge1[i].cost;q.push(node(v,dis[v]));}}}
}inline void init(){memset(head,-1,sizeof(head));memset(head1,-1,sizeof(head1));memset(visited,false,sizeof(visited));memset(dis,MaxN,sizeof(dis));sum=0;cnt=0;cnt1=0;
}
inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;
}
int main()
{int t;cin>>t;while(t--){scanf("%d%d",&n,&m);init();for(int i=0;i<m;i++){int x,y,z;x=read(),y=read(),z=read();add(x,y,z);add1(y,x,z);}
//        for(int i=0;i<cnt;i++) cout<<edge[i].cost<<endl;dij(1);//      cout<<dis[1]<<endl;for(int i=1;i<=n;i++) sum+=dis[i];dij1(1);for(int i=1;i<=n;i++) sum+=dis[i];printf("%lld\n",sum);}return 0;
}

5.Heavy Transportation POJ - 1797
题意:从1点到n点运送货物,每个每两个地方用桥梁链接,每个桥梁都有自己的最大承重,问:最大能运送多重的货物到达目的地。
注意是个无向图,注意每个例子之间多输出一行空行
这个题也是一个并不难的图论题,只不过就是把条件这里一块改了一下,当然,我是不会告诉你我这个题在条件这一块地方wa了好多次。

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn  1010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
struct wazxy{int to,val;wazxy(int a,int b){to=a,val=b;}
};
vector<vector<wazxy> > a;
struct node{int id,dis;node(int a,int b){id=a,dis=b;}bool operator < (const node & a)const{return dis<a.dis;}
};
bool visited[maxn];
int dis[maxn];
void init(){memset(visited,false,sizeof(visited));for(int i=0;i<=maxn;i++) dis[i]=0;a.resize(maxn);a.clear();
}
int n,m;
void dij(){dis[1]=MaxN;priority_queue<node> q;q.push(node(1,MaxN));while(!q.empty()){node temp=q.top();q.pop();if(visited[temp.id]) continue;visited[temp.id]=true;for(int i=0;i<a[temp.id].size();i++){int to=a[temp.id][i].to;if(visited[to]) continue;if(dis[to]<min(temp.dis,a[temp.id][i].val)){dis[to]=min(temp.dis,a[temp.id][i].val);q.push(node(to,dis[to]));}}}
}int main()
{int t;cin>>t;int ans=1;while(t--){init();cin>>n>>m;for(int i=0;i<m;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);a[x].push_back(wazxy(y,z));a[y].push_back(wazxy(x,z));}dij();printf("Scenario #%d:\n",ans++);printf("%d\n",dis[n]);printf("\n");}return 0;
}

6.poj2253(dij变形+优先队列)
题意:就是找出从一个点到另一个点的所有道路,每条道路里都有都有最长的边,然后再从所有最长的边中找出最短的来输出。哦是不是很绕,反正我晕了一会。
跟头顶上的题目十分相似。

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn  1010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
struct wazxy{double to,val;wazxy(double a,double b){to=a,val=b;}
};
vector<vector<wazxy> > a;
struct node{int id;double dis;node(int a,double b){id=a,dis=b;}bool operator < (const node & a)const{return dis>a.dis;}
};
bool visited[maxn];
double dis[maxn];
void init(){memset(visited,false,sizeof(visited));for(int i=0;i<maxn;i++) dis[i]=MaxN;a.resize(maxn);a.clear();
}
int n;
void dij(){dis[1]=MaxN;priority_queue<node> q;q.push(node(1,0));while(!q.empty()){node temp=q.top();q.pop();double d=temp.dis;int u=temp.id;if(visited[u]) continue;for(int i=0;i<a[u].size();i++){wazxy node1=a[u][i];int v=node1.to;double w=node1.val;if(visited[v]) continue;if(dis[v]>max(w,d)){dis[v]=max(w,d);// cout<<dis[v]<<endl;q.push(node(v,dis[v]));}}}
}
struct name{int x,y;
}s[210];
inline double getlen(double x,double y,double x1,double y1){return sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
}int main()
{int cnt=0;while(cin>>n&&n){init();cnt++;for(int i=1;i<=n;i++){cin>>s[i].x>>s[i].y;}for(int i=1;i<=n;i++){for(int f=i+1;f<=n;f++){double temp=getlen(s[i].x,s[i].y,s[f].x,s[f].y);a[i].push_back(wazxy(f,temp));a[f].push_back(wazxy(i,temp));}}dij();printf("Scenario #%d\n",cnt);printf("Frog Distance = %.3f\n\n",dis[2]);//for(int i=1;i<=n;i++) cout<<dis[i]<<endl;}return 0;
}

7.hdu4725The Shortest Path in Nya Graph(建图建图建图+dij+优先队列优化)
搬运一下别人的翻译:n个点,m条边,以及相邻层之间移动的代价c,给出每个点所在的层数,以及m条边,每条边有u,v,c,表示从节点u到v(无向),并且移动的代价 c ,问说从 1 到 n 的代价最小是多少。
mdmdmd建图看别人的建图看了半小时才看懂,然后就是套模板了
其实就是把图层也看成点,对应的编号分别为n+1到n+n

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn  1000010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
int head[maxn];
struct wazxy{int v,w,next;
}edge[maxn];
bool visited[maxn];
bool vis[maxn];
int dis[maxn];
int f[maxn];
int n,m,c;
int cnt;
void init(){cnt=0;memset(visited,false,sizeof(visited));memset(vis,false,sizeof(vis));memset(head,-1,sizeof(head));memset(dis,MaxN,sizeof(dis));
}
void add(int u,int v,int w){edge[cnt].w=w;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;
}
struct node{int n,dis;node(int a,int b){n=a,dis=b;}bool operator < (const node & a)const{return dis>a.dis;}
};
inline void dij(){dis[1]=0;priority_queue<node> q;q.push(node(1,0));while(!q.empty()){node temp=q.top();q.pop();if(visited[temp.n]) continue;visited[temp.n]=true;for(int i=head[temp.n];i!=-1;i=edge[i].next){int v=edge[i].v;if(visited[v]) continue;if(dis[v]>temp.dis+edge[i].w){dis[v]=temp.dis+edge[i].w;q.push(node(v,dis[v]));}}}
}int main()
{int t;cin>>t;int ans=1;while(t--){init();scanf("%d%d%d",&n,&m,&c);for(int i=1;i<=n;i++){scanf("%d",&f[i]);vis[f[i]]=true;}for(int i=1;i<n;i++){if(vis[i]&&vis[i+1]){add(n+i,n+i+1,c);add(n+i+1,n+i,c);}}for(int i=1;i<=n;i++){add(n+f[i],i,0);if(f[i]>1) add(i,n+f[i]-1,c);if(f[i]<n) add(i,n+f[i]+1,c);}int x,y,z;for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z);add(y,x,z);}dij();printf("Case #%d: ",ans++);if(dis[n]<MaxN) printf("%d\n",dis[n]);else printf("-1\n");}return 0;
}

图论刷水题记录(一)(最短路-----dijkstra算法)相关推荐

  1. 图论刷水题记录(二)(最短路-----SPFA算法)

    继第一篇的后续,又来刷水题了,写的是SPFA算法,这个算法的复杂度比较玄学,感觉能不用就不用了,但是他的好处就是可以判断负圈. 3月26日: 1.POJ 1847 Tram 题意:在一个交通网络上有N ...

  2. 图论-最短路Dijkstra算法详解超详 有图解

    整体来看dij就是从起点开始扩散致整个图的过程,为什么说他稳定呢,是因为他每次迭代,都能得到至少一个结点的最短路.(不像SPFA,玄学复杂度) 但是他的缺点就是不能处理带负权值的边,和代码量稍稍复杂. ...

  3. 单源最短路 Dijkstra算法 和 SPFA算法

    单源最短路 •从一个点出发,到达其他顶点的最短路径的长度. •基本操作:松弛 •d[u]+map[u, v]< d[v]这样的边(u,v)称为紧的(tense),可以对它进行松弛(relax): ...

  4. buu 水题记录(一)

    buuctf crypto Before Crypto MD5 Url编码 看我回旋踢 一眼就解密 摩丝 变异凯撒 Quoted-printable Rabbit RSA 篱笆墙的影子 丢失的MD5 ...

  5. 闲来无事刷水题、简单博弈论专题、sg函数、洛谷

    记 今天闲来无事,不想刷codeforces了,到洛谷提高组训练营找几道水题刷着玩玩(虽然自己早已过了打OI的年纪)- 简单博弈论专题 P1199 三国游戏 这么考虑,由于电脑总是不能让我搭配出当前能 ...

  6. 图论 —— 最短路 —— Dijkstra 算法

    [概述] Dijkstra 算法是单源最短路径算法,即计算起点只有一个的情况到其他点的最短路径,其无法处理存在负边权的情况. 其时间复杂度是:O(E+VlogV) [算法分析] 将点分为两类,一类是已 ...

  7. 图论算法讲解--最短路--Dijkstra算法

    一.绪论 要学习最短路算法我们首先应该知道什么是图以及什么是最短路. 图在离散数学中的定义为:图G=(V,E)是一个二元组(V,E)使得E⊆[V]的平方,所以E的元素是V的2-元子集.为了避免符号上的 ...

  8. 03 最短路 dijkstra算法spfa算法floyd算法(附带实例代码) 图论-1

    文章目录 最短路 邻接表的图如下 邻接矩阵如下图 链表实现邻接表实现代码 单源最短路径 Dijkstra 算法 朴素版本 Dijkstra 实现代码 堆优化的dijkstra算法代码实现 Bellma ...

  9. 最短路dijkstra算法详解_最短路径问题---Dijkstra算法详解

    1.Dijkstra算法介绍 · 算法起源: · Djkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家E ...

最新文章

  1. express给html设置缓存,webpack + express 实现文件精确缓存
  2. MyBatis—insert语句返回主键和selectKey标签
  3. 帝国cms栏目忘记设置为终极栏目怎么办?
  4. Python的os.walk()方法详细讲解
  5. 获山东科技最高奖-农业大健康·万书波:沉醉谋定花生增产
  6. SAP programming language培训环境准备 index.html
  7. a20添加usb2net的驱动方法
  8. java setmessage_Java Message.setTitle方法代码示例
  9. 又补充研究了OPENJDK LINUX版本打印变形字体的问题
  10. Dubbo源码解析-Dubbo架构的实现
  11. 20160402系统集成管理工程师(test3)
  12. 如何将两个mp3文件合成一个?
  13. 【集训DAY3】挖金矿【二分答案】
  14. 串口的原始模式和标准模式
  15. tkinter创建嵌套子窗口
  16. win10部署docker后无法启用VMware虚拟机
  17. 已经一点经纬度和距离,计算另一点的经纬度
  18. mysql rank_在MySQL中实现Rank高级排名函数
  19. 【OpenCV】中的鱼眼相机及其标定
  20. 小Y的轮回之路——攒机装机、B150装win7

热门文章

  1. 仅用CPU就能跑到1000FPS,这是开源的C++跨平台人脸检测项目
  2. N 年沉淀,机器学习终于开源!
  3. 链表问题14——在单链表种删除指定值的节点
  4. 代码操作Oracle
  5. 可见面判别算法---可见面判别算法的分类
  6. FastReport 导出pdf时中文乱码的解决办法
  7. mongodb关联查询 和spring data mongodb
  8. 蓝桥杯 校门外面的树 (线段树,区间处理)
  9. 路由器简介一:路由器概念、基本结构及分类
  10. windows域设计best practice