A(附加代码模式)
遍历一遍矩阵算入度出度即可。
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
struct Graph
{
int nodeNumber;
string vexInfo[MAX_SIZE];
int adjMatrix[MAX_SIZE][MAX_SIZE];
};
void CalculateDegree(const Graph &g,int inDegree[],int outDegree[])
{
int n=g.nodeNumber;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(g.adjMatrix[i][j])
inDegree[j]++,
outDegree[i]++;
}
}
return;
}
B
和C是一样的题,只多一步:把出栈顺序储存后输出。
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100];
memset(b,0,sizeof(b));
int n;
cin>>n;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin>>a[i][j];
if(a[i][j]) b[j]++;
}
}
int count=0;
stack<int> s;
for(int i=0;i<n;i++)
{
if(b[i]==0) s.push(i);
}
int c[n];
while(!s.empty())
{
int t=s.top();
s.pop();
c[count]=t;
count++;
for(int i=0;i<n;i++)
{
if(a[t][i]==1)
{
b[i]--;
if(b[i]==0) s.push(i);
}
}
}
if(count<n) cout<<"ERROR"<<endl;
else
{
for(int i=0;i<n;i++)
{
cout<<c[i];
if(i!=n-1) cout<<" ";
else cout<<endl;
}
}
return 0;
}
C
把入度为0的点入栈,然后每次点出栈时就把这个点通向的点入度-1,直到没有点可以入栈为止。判断点数和出栈的点数是否相等。
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100];
int n,m;
while(cin>>n>>m)
{
if(n==0 && m==0) break;
memset(b,0,sizeof(b));
memset(a,0,sizeof(a));
for(int i=0;i<m;i++)
{
int q1,q2;
cin>>q1>>q2;
a[q1-1][q2-1]=1;
b[q2-1]++;
}
int count=0;
stack<int> s;
for(int i=0;i<n;i++)
{
if(b[i]==0) s.push(i);
}
int c[n];
while(!s.empty())
{
int t=s.top();
s.pop();
c[count]=t;
count++;
for(int i=0;i<n;i++)
{
if(a[t][i])
{
b[i]--;
if(b[i]==0) s.push(i);
}
}
}
if(count!=n) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
D
对每个询问,两重循环模拟拓扑排序时的情况,如果序列中的点入度不为0,就输出no。
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100];
int n,m;
cin>>n>>m;
memset(b,0,sizeof(b));
memset(a,0,sizeof(a));
for(int i=0;i<m;i++)
{
int q1,q2;
cin>>q1>>q2;
a[q1][q2]=1;
b[q2]++;
}
int o;
cin>>o;
int c[100],d[100];
for(int r=0;r<o;r++)
{
for(int i=0;i<n;i++)
{
c[i]=b[i];
cin>>d[i];
}
for(int i=0;i<n;i++)
{
int g=d[i];
if(c[g]==0)
{
for(int j=0;j<n;j++)
{
if(a[g][j]) c[j]--;
}
}
else
{
cout<<"NO"<<endl;
break;
}
if(i==n-1) cout<<"YES"<<endl;
}
}
return 0;
}
E
题面描述很有问题,根本看不懂,其实意思就是拓扑排序,每行输入x,y,z表示完成y前必须完成x,耗时为z。求最小时间。
只要在拓扑排序出栈的基础上,用一个数组动态维护最大值就行。
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100];
int n,m;
cin>>n>>m;
memset(b,0,sizeof(b));
memset(a,-1,sizeof(a));
for(int i=0;i<m;i++)
{
int q1,q2;
cin>>q1>>q2;
cin>>a[q1][q2];
b[q2]++;
}
int count=0;
stack<int> s;
int maxm=0,dp[n];
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
{
if(b[i]==0)
{
s.push(i);
dp[i]=0;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[t][i]>=0)
{
if(dp[i]!=-1) dp[i]=max(dp[t]+a[t][i],dp[i]);
else dp[i]=dp[t]+a[t][i];
maxm=max(dp[i],maxm);
b[i]--;
if(b[i]==0)
{
count++;
s.push(i);
}
}
}
}
if(count!=n) cout<<"Impossible"<<endl;
else cout<<maxm<<endl;
return 0;
}
F
F-I这4个题都是J题的一部分。
F和E是一样的题。
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100];
int n,m;
cin>>n>>m;
memset(b,0,sizeof(b));
memset(a,-1,sizeof(a));
for(int i=0;i<m;i++)
{
int q1,q2;
cin>>q1>>q2;
cin>>a[q1][q2];
b[q2]++;
}
int count=0;
stack<int> s;
int maxm=0,dp[n];
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
{
if(b[i]==0)
{
s.push(i);
dp[i]=0;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[t][i]>=0)
{
if(dp[i]!=-1) dp[i]=max(dp[t]+a[t][i],dp[i]);
else dp[i]=dp[t]+a[t][i];
maxm=max(dp[i],maxm);
b[i]--;
if(b[i]==0)
{
count++;
s.push(i);
}
}
}
}
for(int i=0;i<n;i++)
{
cout<<dp[i];
cout<<endl;
}
return 0;
}
G
G题是建立在F题上的题。
F题把最大值找到后,再把图逆过来(其实就是转置邻接矩阵)后再找一遍最大值,然后用第一遍找到的最大值去减。(或者直接维护最小值,效果一样)
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100],c[100];
int n,m;
cin>>n>>m;
memset(b,0,sizeof(b));
memset(a,-1,sizeof(a));
for(int i=0;i<m;i++)
{
int q1,q2;
cin>>q1>>q2;
cin>>a[q1][q2];
b[q2]++;
c[q1]++;
}
int count=0;
stack<int> s;
int maxm=0,dp[n];
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
{
if(b[i]==0)
{
s.push(i);
dp[i]=0;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[t][i]>=0)
{
if(dp[i]!=-1) dp[i]=max(dp[t]+a[t][i],dp[i]);
else dp[i]=dp[t]+a[t][i];
maxm=max(dp[i],maxm);
b[i]--;
if(b[i]==0)
{
count++;
s.push(i);
}
}
}
}
int minm,dp2[n];
memset(dp2,-1,sizeof(dp2));
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
s.push(i);
dp2[i]=maxm;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[i][t]>=0)
{
if(dp2[i]!=-1) dp2[i]=min(dp2[t]-a[i][t],dp2[i]);
else dp2[i]=dp2[t]-a[i][t];
minm=min(dp2[i],minm);
c[i]--;
if(c[i]==0)
{
count++;
s.push(i);
}
}
}
}
for(int i=0;i<n;i++)
{
cout<<dp2[i];
cout<<endl;
}
return 0;
}
H
和F一样的题,注意输出的是什么
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100],c[100];
pair<int,int> d[100];
int n,m;
cin>>n>>m;
memset(b,0,sizeof(b));
memset(a,-1,sizeof(a));
for(int i=0;i<m;i++)
{
int q1,q2;
cin>>q1>>q2;
d[i].first=q1;
d[i].second=q2;
cin>>a[q1][q2];
b[q2]++;
c[q1]++;
}
int count=0;
stack<int> s;
int maxm=0,dp[n];
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
{
if(b[i]==0)
{
s.push(i);
dp[i]=0;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[t][i]>=0)
{
if(dp[i]!=-1) dp[i]=max(dp[t]+a[t][i],dp[i]);
else dp[i]=dp[t]+a[t][i];
maxm=max(dp[i],maxm);
b[i]--;
if(b[i]==0)
{
count++;
s.push(i);
}
}
}
}
int minm,dp2[n];
memset(dp2,-1,sizeof(dp2));
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
s.push(i);
dp2[i]=maxm;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[i][t]>=0)
{
if(dp2[i]!=-1) dp2[i]=min(dp2[t]-a[i][t],dp2[i]);
else dp2[i]=dp2[t]-a[i][t];
minm=min(dp2[i],minm);
c[i]--;
if(c[i]==0)
{
count++;
s.push(i);
}
}
}
}
for(int i=0;i<m;i++)
{
cout<<dp[d[i].first]<<endl;
//cout<<dp2[i];
//cout<<endl;
}
return 0;
}
I
和G一样的题,注意输出的是什么。
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100],c[100];
pair<int,int> d[100];
int n,m;
cin>>n>>m;
memset(b,0,sizeof(b));
memset(a,-1,sizeof(a));
for(int i=0;i<m;i++)
{
int q1,q2;
cin>>q1>>q2;
d[i].first=q1;
d[i].second=q2;
cin>>a[q1][q2];
b[q2]++;
c[q1]++;
}
int count=0;
stack<int> s;
int maxm=0,dp[n];
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
{
if(b[i]==0)
{
s.push(i);
dp[i]=0;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[t][i]>=0)
{
if(dp[i]!=-1) dp[i]=max(dp[t]+a[t][i],dp[i]);
else dp[i]=dp[t]+a[t][i];
maxm=max(dp[i],maxm);
b[i]--;
if(b[i]==0)
{
count++;
s.push(i);
}
}
}
}
int minm,dp2[n];
memset(dp2,-1,sizeof(dp2));
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
s.push(i);
dp2[i]=maxm;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[i][t]>=0)
{
if(dp2[i]!=-1) dp2[i]=min(dp2[t]-a[i][t],dp2[i]);
else dp2[i]=dp2[t]-a[i][t];
minm=min(dp2[i],minm);
c[i]--;
if(c[i]==0)
{
count++;
s.push(i);
}
}
}
}
for(int i=0;i<m;i++)
{
//cout<<dp[d[i].first]<<endl;
cout<<dp2[d[i].second]-a[d[i].first][d[i].second];
//cout<<dp2[i];
cout<<endl;
}
return 0;
}
J
把F-I四个题拼在一起就行。
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 100
int main()
{
int a[100][100];
int b[100],c[100];
pair<int,int> d[100];
int n,m;
cin>>n>>m;
memset(b,0,sizeof(b));
memset(a,-1,sizeof(a));
for(int i=0;i<m;i++)
{
int q1,q2;
cin>>q1>>q2;
d[i].first=q1;
d[i].second=q2;
cin>>a[q1][q2];
b[q2]++;
c[q1]++;
}
int count=0;
stack<int> s;
int maxm=0,dp[n];
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
{
if(b[i]==0)
{
s.push(i);
dp[i]=0;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[t][i]>=0)
{
if(dp[i]!=-1) dp[i]=max(dp[t]+a[t][i],dp[i]);
else dp[i]=dp[t]+a[t][i];
maxm=max(dp[i],maxm);
b[i]--;
if(b[i]==0)
{
count++;
s.push(i);
}
}
}
}
int minm,dp2[n];
memset(dp2,-1,sizeof(dp2));
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
s.push(i);
dp2[i]=maxm;
count++;
}
}
while(!s.empty())
{
int t=s.top();
s.pop();
for(int i=0;i<n;i++)
{
if(a[i][t]>=0)
{
if(dp2[i]!=-1) dp2[i]=min(dp2[t]-a[i][t],dp2[i]);
else dp2[i]=dp2[t]-a[i][t];
minm=min(dp2[i],minm);
c[i]--;
if(c[i]==0)
{
count++;
s.push(i);
}
}
}
}
for(int i=0;i<m;i++)
{
int g1=dp[d[i].first];
int g2=dp2[d[i].second]-a[d[i].first][d[i].second];
if(g1==g2)
{
cout<<d[i].first<<"-->"<<d[i].second<<":"<<g1<<endl;
}
}
return 0;
}