洛谷题单【数据结构1-4】图的基本应用
P5318 【深基18.例3】查找文献
思路
bfs和dfs的模板题
实现
#include<bits/stdc++.h>
using namespace std;
int n,m;
vector<int> a[1000010];
bool visit[1000010];
void dfs(int x,int depth)
{visit[x] = 1;if(depth==n) {cout<<x<<" ";return ;}cout<<x<<" ";for(int i=0;i<a[x].size();i++)if(!visit[a[x][i]]) dfs(a[x][i],depth+1);
}
void bfs()
{queue<int> q;q.push(1);visit[1] = 0;while(!q.empty()){int s = q.front();q.pop();cout<<s<<" ";for(int i=0;i<a[s].size();i++){if(visit[a[s][i]]) {q.push(a[s][i]);visit[a[s][i]] = 0;}}}
}
int main()
{cin>>n>>m;int t1,t2;for(int i=1;i<=m;i++){cin>>t1>>t2;a[t1].push_back(t2);}for(int i=1;i<=n;i++)sort(a[i].begin(),a[i].end());dfs(1,1);cout<<endl;bfs();
}
P3916 图的遍历
思路
反向建立边,从节点最大的开始dfs,把沿途所有点的值都修改
实现
#include<bits/stdc++.h>
using namespace std;
#define MAXL 100010int N, M, A[MAXL];
vector<int> G[MAXL]; void dfs(int x, int d) {if(A[x]) return; A[x] = d;for(int i=0; i<G[x].size(); i++)dfs(G[x][i], d);
}int main() {int u, v;scanf("%d%d", &N, &M);for(int i=1; i<=M; i++) {scanf("%d%d", &u, &v);G[v].push_back(u); }for(int i=N; i; i--) dfs(i, i); for(int i=1; i<=N; i++) printf("%d ", A[i]);printf("\n");return 0;
}
P1113 杂务
思路
拓扑排序
本题数据特殊,是有序的。因此可以在输入时处理,建图意义不大
实现
//来自Nishikino_Curtis
#include<bits/stdc++.h>
using namespace std;
int n,l,t,ans[10005],maxans;
int main()
{scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d",&i);scanf("%d",&l);int tmp=0;while(scanf("%d",&t)&&t)tmp=max(ans[t],tmp);ans[i]=tmp+l;maxans=max(ans[i],maxans);} printf("%d\n",maxans);return 0;}
P4017 最大食物链计数
思路
边拓扑排序边维护从生产者到该节点有多少条路(路的条数等于所有指向它的节点的路的条数之和)
实现
一个有错误的实现 有空改改
#include<bits/stdc++.h>
using namespace std;
const int N = 5010;
int h[N], e[N], ne[N], idx;
int q[N], d[N];
int ans[N];
int n,m;
void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
int topsort()
{int hh = 0, tt = -1;// d[i] 存储点i的入度for (int i = 1; i <= n; i ++ )if (!d[i])q[ ++ tt] = i;while (hh <= tt){int t = q[hh ++ ];
// cout<<endl;
// cout<<t<<" ";for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];
// cout<<j;ans[j] += ans[t];ans[j]%=80112002;if (-- d[j] == 0)q[ ++ tt] = j;}}// 如果所有点都入队了,说明存在拓扑序列;否则不存在拓扑序列。return q[tt];
}
int main()
{idx = 0;memset(h, -1, sizeof h);cin>>n>>m;vector<bool> eat(n+1,0);int t1,t2;for(int i=0;i<m;i++){scanf("%d%d",&t1,&t2);d[t2]++;add(t1,t2);eat[t1] = 1;}int res = 0;ans[1] = 1; topsort();for(int i=1;i<=n;i++){if(!eat[i])res = (ans[i]+res)%80112002;}cout<<res;return 0;}
P1807 最长路
思路
给边权求相反数,转换为求最短路问题
实现
#include<bits/stdc++.h>
using namespace std;
int main(){int dis[50001],w[50001],n,m,minn,f[50001][3];scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){dis[i]=w[i]=100000000;f[i][1]=f[i][2]=0;}for(int i=1;i<=m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);f[i][1]=a,f[i][2]=b,w[i]=-c;}dis[1]=0;for(int i=1;i<=n-1;i++){for(int j=1;j<=m;j++){dis[f[j][2]]=min(dis[f[j][2]],dis[f[j][1]]+w[j]);}}if(dis[n]!=0)printf("%d",-dis[n]);else printf("-1");return 0;
}
P2853 [USACO06DEC]Cow Picnic S
思路
从k个奶牛出发,dfs且记录每一个牧场被遍历的次数。被遍历次数等于k的牧场符合条件。
实现
#include<bits/stdc++.h>
using namespace std;
bool vis[1010];
int k,n,m,ans;
int mk[1010],a[1010];
vector <int> b[1010];
void dfs(int x)
{vis[x]=1; mk[x]++;for(int i=0;i<b[x].size();i++)if(!vis[b[x][i]])dfs(b[x][i]);
}
int main()
{int x,y;cin>>k>>n>>m;for(int i=1;i<=k;i++) cin>>a[i];for(int i=1;i<=m;i++) {cin>>x>>y;b[x].push_back(y);}for(int i=1;i<=k;i++) { for(int j=1;j<=n;j++) vis[j]=0; dfs(a[i]);}for(int i=1;i<=n;i++) if(mk[i]==k) ans++;cout<<ans;return 0;
}
P1347 排序
思路
自己写出来不对 绿题果然还是难的 = =
来自题解区 mydiplomacy
- 条件有矛盾:没有点入度为0,或者最后在队列里的节点数<n
- 条件不足:有不止一个点入度为零,或当取同一个队首u时有不止一个v的入度变成了零
- 排序成功:非上两种情况
实现
来自题解区 mydiplomacy
#include<bits/stdc++.h>
using namespace std;
const int maxn=30,maxm=905;struct Node
{int v;Node *next;
}*h[maxn],pool[maxm];
int tot;
int du[maxn];
int q[maxn],head,tail;
int n,m;void addEdge(int u, int v)
{Node *p=&pool[++tot];p->v=v; p->next=h[u]; h[u]=p;
}int toposort() //返回值为1代表成立,返回值为0代表条件不足,返回值为-1代表条件矛盾
{int temp=0;int f=0;for(int i=1;i<=n;i++){if(du[i]==0){q[tail++]=i;temp++;} }if(temp>1)f=1;while(head<tail){temp=0;int u=q[head++];for(Node *p=h[u];p;p=p->next){du[p->v]--;if(du[p->v]==0){q[tail++]=p->v;temp++;}}if(temp>1)f=1;}if(tail!=n)return -1;elseif(f==1)return 0;else return 1;
} struct Edge
{int u,v;
}a[maxm];int main()
{cin>>n>>m;for(int i=1;i<=m;i++){char aa,bb,cc;cin>>aa>>bb>>cc;a[i].u=aa-'A'+1; a[i].v=cc-'A'+1;}for(int i=1;i<=m;i++){addEdge(a[i].u,a[i].v);head = tail = 0;memset(du,0,sizeof(du));for(int j=1;j<=i;j++) du[a[j].v]++;int flag=toposort();if(flag==1){cout<<"Sorted sequence determined after "<<i<<" relations: ";for(int j=0;j<=n-1;j++){cout<<(char)(q[j]+'A'-1);}cout<<'.'<<endl;return 0;}else if(flag==0) continue;else{cout<<"Inconsistency found after ";cout<<i<<" relations."<<endl;return 0;}}cout<<"Sorted sequence cannot be determined."<<endl;return 0;
}
P1983 [NOIP2013 普及组] 车站分级
思路
建图时添加从停靠站到未停靠站的边,拓扑排序记录一共有几层
实现
来自 黄毛猫_HYX
#include<bits/stdc++.h>
#define N 1005
using namespace std;
int n,m,ans,st[N],s,tuopu[N][N],de[N],tt[N],top;
bool is[N],bo[N];
int main() {scanf("%d %d",&n,&m);for(int i=1;i<=m;i++) {memset(is,0,sizeof(is));//is表示是否是停靠站scanf("%d",&s);for(int j=1;j<=s;j++)scanf("%d",&st[j]),is[st[j]]=true;for(int j=st[1];j<=st[s];j++)if(!is[j]) //枚举站点,若不是已停靠的就小于所有停靠站的等级for(int k=1;k<=s;k++) //枚举已停靠站点if(!tuopu[j][st[k]]) tuopu[j][st[k]]=1,de[st[k]]++;//tuopu[i][j]表示j>i的级别,如上}do{top=0;for(int i=1;i<=n;i++)if(de[i]==0&&!bo[i]) {tt[++top]=i,bo[i]=true;//开始将出度为0的点删掉}for(int i=1;i<=top;i++)for(int j=1;j<=n;j++)if(tuopu[tt[i]][j]) tuopu[tt[i]][j]=0,de[j]--;//去边去点ans++;} while(top);printf("%d",ans-1);//最后一次什么点都没有会多算一次(自行理解)return 0;
}
欢迎指正
洛谷题单【数据结构1-4】图的基本应用相关推荐
- 【洛谷OJ C++】洛谷题单101 入门2分支结构 题解及学习笔记
洛谷题单101链接:https://www.luogu.com.cn/training/101#problems 笔记及题解目录: 学习笔记: P5710 [深基3.例2]数的性质 P5711 [深基 ...
- 洛谷题单 算法1-3 暴力枚举
1 First Step (ファーストステップ) 题目背景 知らないことばかりなにもかもが(どうしたらいいの?) 一切的一切 尽是充满了未知数(该如何是好) それでも期待で足が軽いよ(ジャンプだ!) ...
- 【洛谷OJ C++】洛谷题单100 入门1顺序结构 题解及学习笔记
洛谷平台题单100链接:https://www.luogu.com.cn/training/100#problems 目录 学习笔记: P1001 A+B Problem P1000 超级玛丽游戏 P ...
- 洛谷 题单2分支结构(freshman锻炼牛犇勿喷)
第一题数的性质 题目描述 一些数字可能拥有以下的性质: 性质 1:是偶数: 性质 2:大于 4 且不大于 12. 小A 喜欢这两个性质同时成立的数字:Uim 喜欢这至少符合其中一种性质的数字:八尾勇喜 ...
- 洛谷题单的Python版题解(有需要的小伙伴可以来看看哦~!)
我的洛谷博客 记得从这里搜索题目,分类有些问题.
- 洛谷题单难题总结——数组
第一题:旗鼓相当的对手 题目描述 有N个同学,每个同学三科成绩(每门分数<=150),如果两名同学<i,j>的总分不超过10分且单科分差不超过5分,则两个同学是旗鼓相当的对手,求总对 ...
- 洛谷题单1-7 搜索题解
P1219 [USACO1.5]八皇后 Checker Challenge 这个是我最最开始的写法,也是篇幅最大的写法,每放一个棋子就考虑放这个棋子满不满足 每行每列,左斜线和右斜线都只有一个棋子,注 ...
- 洛谷题单 算法1-1 模拟和高精度
1 乒乓球 题目背景 国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及.其中11分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役.华华就是其中 ...
- 洛谷题单 算法2-1 前缀和与差分
前缀和是一种重要的预处理,能大大降低查询的时间复杂度,而差分则是一种和前缀和相对的策略. 海底高铁 题目背景 大东亚海底隧道连接着厦门.新北.博艾.那霸.鹿儿岛等城市,横穿东海,耗资1000亿博艾元, ...
最新文章
- 最年轻和最年长新院士:一个是数学神童 一个曾是氮肥厂工人
- 关于Java为什么配置好环境变量但是不能在命令行cmd运行javac的问题
- ERICA:提升预训练语言模型实体与关系理解的统一框架
- python中的装饰器有哪些-Python中的@函数装饰器到底是什么?
- lucene索引word/pdf/html/txt文件及检索(搜索引擎)
- hantzsch酯_有机人名反应——Hantzsch吡啶合成
- 【JavaScript】callee 与 caller
- 前端使用js来获取ip起始和结束地址
- 对于8086cpu的探索发现
- 2022年建筑架子工(建筑特殊工种)考试资料及建筑架子工(建筑特殊工种)新版试题
- Unity5.0 天空盒(CubeMap)
- Python基础知识笔记——补充
- 切比雪夫,霍夫丁不等式证明
- 计算机木马犯罪类型,计算机木马病毒犯罪研究..doc
- 程序员能纯靠技术渡过中年危机吗
- 浙江大学计算机系81级同学会,无线电系64级校友毕业50周年聚会
- BIOS、UEFI、Boot Loader都是些什么
- 有些不知道自己应该做些什么
- S5720 telnet配置后无法登陆
- 美团外卖没有淡季,只因具备“铁三角结构优势”