(7条消息) 食用前须知(阅读并同意后在食用其他部分)_lxrrrrrrrr的博客-CSDN博客
看完进来哈
目录
问题 A: 邻接矩阵存储的图,节点的出度和入度计算(附加代码模式)
---------------------------------------概念-----------------------------------------
--------------------------------------------------------------------------------------
模拟即可
- #include
- using namespace std;
- #define MAX_SIZE 200
- struct Graph{
- int nodeNumber;
- int adjMatrix[MAX_SIZE][MAX_SIZE];
- };
- void CalculateDegree(const Graph& g,int inDegree[],int outDegree[]){
- int n=g.nodeNumber;
- for(int i=0;i
- for( int j=0;j
- if(g.adjMatrix[i][j]==0){
- continue;
- }
- inDegree[j]+=1;
- outDegree[i]+=1;
- }
- }
- }
问题 B: 算法7-12:有向无环图的拓扑排序
拓扑排序板子
从每个入度为0的点开始宽搜即可
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- int G[1000][1000];
- int n;
- int du[1000];
- vector<int> ans;
- bool tpst() {
- int num=0;
- stack<int> q;
- fer(i,0,n-1){
- if(du[i]==0){
- q.push(i);
- }
- }
- while(q.size()) {
- int u=q.top();
- q.pop();
- ans.pb(u);
- num++;
- fer(v,0,n-1){
- if(G[u][v]) {
- du[v]--;
- if(du[v]==0)
- q.push(v);
- }
- }
- }
- if(num==n){
- return true;
- }
- else{
- return false;
- }
- }
- signed main()
- {
- cin>>n;
- fer(i,0,n-1){
- fer(j,0,n-1){
- cin>>G[i][j];
- if(G[i][j]){
- du[j]++;
- }
- }
- }
- if(tpst()) {
- for(auto t:ans){
- cout<
" "; - }
- cout<<'\n';
- }
- else{
- cout <<"ERROR\n";
- }
- }
问题 C: 有向图是否存在环?
判环的话
并查集好写一点
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- int p[N];
- int find(int x){
- if(p[x]!=x) p[x]=find(p[x]);
- return p[x];
- }
-
- signed main(){
- int n,m;
- while(cin>>n>>m){
- if(!n && !m) break;
- fer(i,1,n) p[i]=i;
- bool fl=false;
- fer(i,1,m){
- int a,b;
- cin>>a>>b;
- if(find(a)!=find(b)){
- p[find(a)]=find(b);
- }
- else{
- fl=1;
- break;
- }
- }
- if(fl){
- cout<<"YES\n";
- }
- else{
- cout<<"NO\n";
- }
- }
- }
问题 D: 是否为有效的拓扑序列
计算一下度数即可
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- vector<int> v[N];
- int inv[N];
- int now[N];
- int n,m;
- int inx[N];
- bool check(){
- fer(i,0,n) now[i]=inv[i];
- for(int i=0;i
- cin>>inx[i];
- }
- for(int i=0;i
- if(now[inx[i]]!=0){
- return false;
- }
- for(int j=0;j
size();j++){ - now[v[inx[i]][j]]--;
- }
- }
- return true;
- }
- signed main(){
- cin>>n>>m;
- fer(i,1,m){
- int a,b;
- cin>>a>>b;
- v[a].pb(b);
- inv[b]++;
- }
- int k;
- cin>>k;
- fer(i,1,k){
- if(check()){
- cout<<"YES"<
- }
- else cout<<"NO"<
- }
-
- }
问题 E: 案例6-2.6:最短工期
拓扑排序不那么板子的板子题
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- int tmp[N];
- int h[N],e[N],ne[N],w[N],idx;
- int d[N],ans[N];
- queue<int> q;
- void add(int a,int b,int f){
- e[idx]=b,w[idx]=f,ne[idx]=h[a],h[a]=idx++;
- }
- int n,m;
- void solve(){
- int ans=0;
- while(!q.empty()){
- int t=q.front();
- q.pop();
- for(int i=h[t];i!=-1;i=ne[i]){
- d[e[i]]--;
- if(d[e[i]]==0) q.push(e[i]);
- tmp[e[i]]=max(tmp[e[i]],w[i]+tmp[t]);
- ans=max(ans,tmp[e[i]]);
- }
- }
- fer(i,0,n-1){
- if(d[i]!=0){
- cout<<"Impossible\n";
- return;
- }
- }
- cout<
'\n'; - }
- signed main(){
- memset(h,-1,sizeof h);
- cin>>n>>m;
- fer(i,1,m){
- int a,b,c;
- cin>>a>>b>>c;
- add(a,b,c);
- d[b]++;
- }
- fer(i,0,n-1){
- if(d[i]==0){
- q.push(i);
- tmp[i]=0;
- }
- }
- solve();
- }
---------------------------------------概念-----------------------------------------

作业上的概念模糊不清,这里稍作解释,是离散数学中的概念
我们以这张图为例
最早发生时间:
从前往后,前驱结点到当前结点所需时间,取最大值。
如上图中的节点4有两个前驱结点(节点2和3),节点2到节点4的最早发生时间是a1+a3也就是8,节点3到节点4的最早发生时间是a2+a4也就是12,因为12>8,所以节点4的最早发生时间是12.
最迟发生时间:
从后往前,后继结点的最迟发生时间-边权值,取最小值。
也就是求一次最早发生时间,再从出度为0的点反向更新回来求出每个点的最迟时间

关键路径:
最早发生时间和最迟发生时间相同的结点即为关键路径上的节点。
也就是两个都要求一遍呗
而边的最早最迟发生时间大家看作业上的图就知道了,就是看对应的点的最早最迟发生时间
所以我们可以先求点的然后在遍历一遍求出边的最早最迟发生时间
--------------------------------------------------------------------------------------
下列代码我没有用拓扑排序写
而是直接宽搜的,然后松弛
拓扑排序本质就是bfs呗
因为后续涉及到对边的操作,所以我用了链式前向星存图
不懂可以csdn一下,很简单的
问题 F: 图-节点的最早发生时间
边bfs边更新每个点的答案
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- int h[N],w[N],e[N],ne[N],idx;
- void add(int a, int b, int c)
- {
- e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++ ;
- }
- int dist[N];
- int n,m;
- void bfs(){
- memset(dist,0,sizeof dist);
- dist[1]=0;
- queue<int> q;
- q.push(1);
- while(q.size()){
- auto tp=q.front();
- q.pop();
- for(int i=h[tp];i!=-1;i=ne[i]){
- int j=e[i];
- if(w[i]+dist[tp]>dist[j]){
- dist[j]=dist[tp]+w[i];
- q.push(j);
- }
- }
- }
- }
- signed main(){
- memset(h,-1,sizeof h);
- cin>>n>>m;
- fer(i,1,m){
- int a,b,w;
- cin>>a>>b>>w;
- add(a+1,b+1,w);
- }
- bfs();
- fer(i,1,n){
- cout<
'\n'; - }
- }
问题 G: 图-节点的最迟发生时间
我们需要建两张图,一张正向图一张反向图
从第一张图bfs出去求出最早时间,然后在第二张图反向bfs一遍
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- int h[N],w[N],e[N],ne[N],idx;
- int h2[N],w2[N],e2[N],ne2[N],idx2;
- void add1(int a, int b, int c)
- {
- e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++ ;
- }
- void add2(int a, int b, int c)
- {
- e2[idx2]=b,w2[idx2]=c,ne2[idx2]=h2[a],h2[a]=idx2++ ;
- }
- int dist[N];
- int dist2[N];
- int n,m;
- void bfs(){
- memset(dist,0,sizeof dist);
- dist[1]=0;
- queue<int> q;
- q.push(1);
- while(q.size()){
- auto tp=q.front();
- q.pop();
- for(int i=h[tp];i!=-1;i=ne[i]){
- int j=e[i];
- if(w[i]+dist[tp]>dist[j]){
- dist[j]=dist[tp]+w[i];
- q.push(j);
- }
- }
- }
- memset(dist2,0x3f,sizeof dist2);
- queue<int> q2;
- fer(i,1,n){
- if(h[i]==-1){
- dist2[i]=dist[i];
- q2.push(i);
- }
- }
-
- while(q2.size()){
- auto tp=q2.front();
- q2.pop();
- for(int i=h2[tp];i!=-1;i=ne2[i]){
- int j=e2[i];
- if(dist2[tp]-w2[i]
- dist2[j]=dist2[tp]-w2[i];
- q2.push(j);
- }
- }
- }
- }
- int res[N];
- signed main(){
- memset(h,-1,sizeof h);
- memset(h2,-1,sizeof h2);
- cin>>n>>m;
- fer(i,1,m){
- int a,b,w;
- cin>>a>>b>>w;
- add1(a+1,b+1,w);
- add2(b+1,a+1,w);
- }
- bfs();
- fer(i,1,n){
- cout<
"\n"; - }
- }
问题 H: 图-边的最早发生时间
和点的最早发生时间一样
这条边是那个点引出来的答案就和这个点的最早发生时间一样
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- int h[N],w[N],e[N],ne[N],idx;
- int res[N];
- void add(int a, int b, int c)
- {
- e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++ ;
- }
- int dist[N];
- int n,m;
- void bfs(){
- memset(dist,0,sizeof dist);
- dist[1]=0;
- queue<int> q;
- q.push(1);
- while(q.size()){
- auto tp=q.front();
- q.pop();
- for(int i=h[tp];i!=-1;i=ne[i]){
- int j=e[i];
- if(w[i]+dist[tp]>dist[j]){
- dist[j]=dist[tp]+w[i];
- q.push(j);
- }
- }
- }
- }
- signed main(){
- memset(h,-1,sizeof h);
- cin>>n>>m;
- fer(i,1,m){
- int a,b,w;
- cin>>a>>b>>w;
- add(a+1,b+1,w);
- }
- bfs();
- fer(node,1,n){
- for(int i=h[node];i!=-1;i=ne[i]){
- res[i]=dist[node];
- }
- }
- fer(i,0,m-1){
- cout<
'\n'; - }
- }
问题 I: 图-边的最迟发生时间
和点的最迟发生时间一样
这条边指向那个点的答案就是这个点的最迟发生时间减去权值
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- int h[N],w[N],e[N],ne[N],idx;
- int h2[N],w2[N],e2[N],ne2[N],idx2;
- void add1(int a, int b, int c)
- {
- e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++ ;
- }
- void add2(int a, int b, int c)
- {
- e2[idx2]=b,w2[idx2]=c,ne2[idx2]=h2[a],h2[a]=idx2++ ;
- }
- int dist[N];
- int dist2[N];
- int n,m;
- void bfs(){
- memset(dist,0,sizeof dist);
- dist[1]=0;
- queue<int> q;
- q.push(1);
- while(q.size()){
- auto tp=q.front();
- q.pop();
- for(int i=h[tp];i!=-1;i=ne[i]){
- int j=e[i];
- if(w[i]+dist[tp]>dist[j]){
- dist[j]=dist[tp]+w[i];
- q.push(j);
- }
- }
- }
- memset(dist2,0x3f,sizeof dist2);
- queue<int> q2;
- fer(i,1,n){
- if(h[i]==-1){
- dist2[i]=dist[i];
- q2.push(i);
- }
- }
-
- while(q2.size()){
- auto tp=q2.front();
- q2.pop();
- for(int i=h2[tp];i!=-1;i=ne2[i]){
- int j=e2[i];
- if(dist2[tp]-w2[i]
- dist2[j]=dist2[tp]-w2[i];
- q2.push(j);
- }
- }
- }
- }
- int res[N];
- signed main(){
- memset(h,-1,sizeof h);
- memset(h2,-1,sizeof h2);
- cin>>n>>m;
- fer(i,1,m){
- int a,b,w;
- cin>>a>>b>>w;
- add1(a+1,b+1,w);
- add2(b+1,a+1,w);
- }
- bfs();
- fer(node,1,n){
- for(int i=h[node];i!=-1;i=ne[i]){
- int j=e[i];
- res[i]=dist2[j]-w[i];
- }
- }
- fer(i,0,m-1){
- cout<
'\n'; - }
- }
问题 J: 图-图的关键路径
两个都求一边
然后看相等
- #include
- #define int long long
- #define pb push_back
- #define fer(i,a,b) for(int i=a;i<=b;++i)
- #define der(i,a,b) for(int i=a;i>=b;--i)
- #define all(x) (x).begin(),(x).end()
- #define pll pair
- #define et cout<<'\n'
- #define xx first
- #define yy second
- using namespace std;
- const int N=1e6+10;
- int h[N],w[N],e[N],ne[N],idx;
- int h2[N],w2[N],e2[N],ne2[N],idx2;
- void add1(int a, int b, int c)
- {
- e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++ ;
- }
- void add2(int a, int b, int c)
- {
- e2[idx2]=b,w2[idx2]=c,ne2[idx2]=h2[a],h2[a]=idx2++ ;
- }
- int dist[N];
- int dist2[N];
- int n,m;
- void bfs(){
- memset(dist,0,sizeof dist);
- dist[1]=0;
- queue<int> q;
- q.push(1);
- while(q.size()){
- auto tp=q.front();
- q.pop();
- for(int i=h[tp];i!=-1;i=ne[i]){
- int j=e[i];
- if(w[i]+dist[tp]>dist[j]){
- dist[j]=dist[tp]+w[i];
- q.push(j);
- }
- }
- }
- memset(dist2,0x3f,sizeof dist2);
- queue<int> q2;
- fer(i,1,n){
- if(h[i]==-1){
- dist2[i]=dist[i];
- q2.push(i);
- }
- }
-
- while(q2.size()){
- auto tp=q2.front();
- q2.pop();
- for(int i=h2[tp];i!=-1;i=ne2[i]){
- int j=e2[i];
- if(dist2[tp]-w2[i]
- dist2[j]=dist2[tp]-w2[i];
- q2.push(j);
- }
- }
- }
- }
- int res[N];
- int res2[N];
- vector
edge; - signed main(){
- memset(h,-1,sizeof h);
- memset(h2,-1,sizeof h2);
- cin>>n>>m;
- fer(i,1,m){
- int a,b,w;
- cin>>a>>b>>w;
- edge.push_back({a,b});
- add1(a+1,b+1,w);
- add2(b+1,a+1,w);
- }
- bfs();
- fer(node,1,n){
- for(int i=h[node];i!=-1;i=ne[i]){
- res[i]=dist[node];
- }
- }
- fer(node,1,n){
- for(int i=h[node];i!=-1;i=ne[i]){
- int j=e[i];
- res2[i]=dist2[j]-w[i];
- }
- }
- fer(i,0,m-1){
- if(res[i]==res2[i]){
- cout<
"-->"<":"<'\n'; - }
- }
- }
-
相关阅读:
大数据培训课程之序列化案例实操
人工智能轨道交通行业周刊-第14期(2022.9.12-9.18)
wsl-Ubuntu18.04子系统使用cuda
SpringBoot篇---第四篇
js脚本化css
六、鼎捷T100生产管理之生产入库管理篇
Git代码回归到指定commit
解决mybatis用Map返回的字段全变大写的问题
分布式环境下的接口幂等性
【开发篇】三、web下单元测试与mock数据
-
原文地址:https://blog.csdn.net/m0_61735576/article/details/127927479