图论-存储&最短路
来源:互联网 发布:ucloud云计算创始人 编辑:程序博客网 时间:2024/06/05 05:10
今天讲图论......
基础就开心地跳过
图的存储
邻接矩阵没什么,注意一下初始化就好了,主要是邻接表。
曾经pascal用的指针,现在用的是静态链表,感觉很six。
const int MAXN=10010,MAXM=10010; struct line{int y,next;//如果有权值还要再开一个变量}l[MAXM];int n,m,f[MAXN]={0},num=0;inline void init(){int a,b;scanf("%d%d",&n,&m);//n个顶点,m条边 for(int i=1;i<=m;++i){scanf("%d%d",&a,&b);l[++num].y=b;//加入新的一个节点l[num].next=f[a];f[a]=num; //这里num可直接用i,无向图要反过来再存储一次 }return;}图的最短路
有很多种做法......
洛谷p1529回家
我用的Floyed(当然了,这题有很多算法)它的思想类似dp,但是时间复杂度很高,数据范围大就会gg。
Floyed的k在最外层,个人理解是一个个加入顶点,判断能否松弛。
#include<bits/stdc++.h>using namespace std;int s[60]={0},f[55][55],p;inline void init(){ memset(f,10,sizeof(f));//用邻接矩阵存储 char x,y,t[10]; int xx,yy,z; scanf("%d",&p);gets(t); for(int i=1;i<=p;i++)//读入很恶心,啊 { scanf("%c %c %d",&x,&y,&z); if(x>='A'&&x<='Z')s[x-'A'+1]=1,xx=x-'A'+1; else xx=x-'a'+27; if(y>='A'&&y<='Z')s[y-'A'+1]=1,yy=y-'A'+1; else yy=y-'a'+27; if(z<f[xx][yy])f[xx][yy]=f[yy][xx]=z; gets(t); } s[26]=0; for(int i=1;i<=52;i++)f[i][i]=0; return;}inline void floyd(){for(int k=1;k<=52;k++)//k在最外层哦for(int i=1;i<=52;i++)for(int j=1;j<=52;j++)f[i][j]=min(f[i][j],f[i][k]+f[k][j]);return;}inline void print(){ int mi=100000,k; for(int i=1;i<=51;i++) if(s[i]==1&&f[i][26]<mi) { mi=f[i][26]; k=i; } printf("%c %d",'A'+k-1,mi); return;}int main(){init();floyd();print();return 0;}
洛谷p1339热浪
来一个dijkstra吧~
不断把离源点最近的点加入已搜索的行列(?
然后用这个点更新其余点的最短距离,不断重复。
#include<bits/stdc++.h>using namespace std;int ans[2600][2600],n,m,b,e,sum[2600]={0};int flag[2600]={0};inline void init(){ scanf("%d%d%d%d",&n,&m,&b,&e); memset(ans,10,sizeof(ans)); for(int i=1;i<=n;i++)ans[i][i]=0; for(int i=1;i<=m;i++)//为了初始化方便用的邻接矩阵 { int x,y,v; scanf("%d%d%d",&x,&y,&v); if(ans[x][y]>v)ans[x][y]=ans[y][x]=v; } return;}inline void di(){ for(int i=1;i<=n;i++)sum[i]=ans[b][i];//初始化 flag[b]=1; for(int i=1;i<n;i++) { int mi=100000,k=0; for(int j=1;j<=n;j++)//贪心一波 if(flag[j]==0&&sum[j]<mi) { mi=sum[j]; k=j; } if(k==0)return; flag[k]=1;//加入已搜队伍 for(int j=1;j<=n;j++)//更新其余点最短距离 if(flag[j]==0)sum[j]=min(sum[j],sum[k]+ans[j][k]); if(flag[e]==1)return; } return;}int main(){ init(); di(); printf("%d",sum[e]); return 0;}洛谷p1828香甜的黄油
就决定是你了,Bellman-ford!
这题刚开始害怕复杂度,但是裸的Bellman-ford居然过了,emmmm......
bellman-ford的思想是用不断每一条边更新最短距离直到不再更新,
如果更新n次后仍未更新完,则说明有负权环(一条路径最多经过n个点,含n-1条边)。
#include<bits/stdc++.h>using namespace std;struct line{int l,r,w;}l[1500];int s[900][900],a[900]={0},n,p,c,flag[900],sum[900],num=0;int ans=1000000;inline void init(){scanf("%d%d%d",&n,&p,&c);for(int i=1;i<=n;i++){int t;scanf("%d",&t);a[t]++;//计算每个牧场的奶牛数}for(int i=1;i<=p;i++)for(int j=1;j<=p;j++)s[i][j]=100000;for(int i=1;i<=p;i++)s[i][i]=0;for(int i=1;i<=c;i++){int x,y,v;scanf("%d%d%d",&x,&y,&v);if(s[x][y]>v)//为了不重复,弄了个实际没什么用的邻接矩阵{ s[x][y]=s[y][x]=v; l[++num].l=x; l[num].r=y; l[num].w=v; l[++num].r=x; l[num].l=y; l[num].w=v;}}return;}inline void bell(int b){for(int i=1;i<=p;i++)sum[i]=100000;sum[b]=0;for(int i=1;i<=p;i++){bool re=false;for(int j=1;j<=num;j++)if(sum[l[j].l]+l[j].w<sum[l[j].r]){sum[l[j].r]=sum[l[j].l]+l[j].w;re=true;}if(re==false)break;}int ss=0;for(int i=1;i<=p;i++)ss+=a[i]*sum[i];ans=min(ans,ss);return;}int main(){ init();for(int i=1;i<=p;i++)di(i);printf("%d",ans);return 0;}
洛谷p3371模版题
这题我用了SPFA,思路是运用队列优化Bellman-ford,
如果当前加入的边可以松弛,则将该边的末端点加入队列等待松弛。
#include<bits/stdc++.h>using namespace std; const int MAXN=10010,MAXM=500010; struct line{int y,next,w;}l[MAXM];int n,m,f[MAXN]={0},num=0,begin;int ans[MAXN],flag[MAXN]={0},q[MAXN*MAXN]={0};inline void init(){int a,b,v;scanf("%d%d%d",&n,&m,&begin);for(int i=1;i<=m;++i){scanf("%d%d%d",&a,&b,&v);l[++num].y=b;l[num].w=v;l[num].next=f[a];f[a]=num;}return;}inline void spfa(int b){ans[b]=0;flag[b]=1;int head=1,tail=1;q[head]=b;while(head<=tail){int t=q[head];for(int i=f[t];i;i=l[i].next)if(ans[t]+l[i].w<ans[l[i].y]){ans[l[i].y]=ans[t]+l[i].w;if(flag[l[i].y]==0){q[++tail]=l[i].y;flag[l[i].y]=1;}}head++;flag[t]=0;//出队后要改变该点为可入队!!! }return;}int main(){init();for(int i=1;i<=n;i++)ans[i]=2147483647;spfa(begin);for(int i=1;i<n;i++)printf("%d ",ans[i]);printf("%d",ans[n]);return 0;}有时间写个比较吧(flag
阅读全文
3 0
- 图论-存储&最短路
- 【图论01】最短路 1001 最短路
- 图论 最短路 Dijkstra
- 【图论】最短路
- 图论-最短路问题
- 图论-最短路-floyd
- 图论 C - 最短路
- 图论-最短路问题
- 【模板】【图论】最短路
- 图论--最短路算法
- 图论-最短路
- 图论 最短路 poj 1062
- acm_图论_最短路
- 图论-最短路-BF算法
- 图论-最短路-dijkstra算法
- 图论 最短路 difjstra 专题
- 图论 最短路 Bellman_Ford 专题
- 图论_最短路问题
- 最大子序列和问题
- 3. Longest Substring Without Repeating Characters
- 搭建AngularJS开发Webapp的开发环境-安装bower
- 电商营销方式抢购,秒杀Redis原子出队列lpop方法作为剩余库存判断条件的实现方式(2)
- 爬虫之爬取微博
- 图论-存储&最短路
- 3226: [Sdoi2008]校门外的区间
- Maven modules 生产环境 开发环境搭建
- Canvas的实际使用--自定义搜索效果
- 电商营销方式抢购,秒杀Redis原子减decr方法作为剩余库存判断条件的实现方式(1)
- servlet 的接口简单应用和filter过滤 用户未登录
- 电商营销方式抢购,秒杀Redis原子减decr方法作为剩余库存判断条件的实现方式(1)
- permutohedral lattice
- 二叉平衡树-AVL