PAT(甲级)2020年秋季考试 7-4 Professional Ability Test
Posted CSU迦叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT(甲级)2020年秋季考试 7-4 Professional Ability Test相关的知识,希望对你有一定的参考价值。
解题思路:
1.用拓扑排序判断给定的图是否是有向无环图(DAG)
在这个过程当中,对于入度为0的结点,在布尔数组中标记是初始结点
通过入队的结点个数是否等于总个数判断是不是DAG
注意:虽然有队列,但是不需要inq[]数组标记是否入队,当弹出一个元素时,再让计数加一
当一个结点出队,不要把对应的邻接向量清空,不然后面的迪杰斯特拉没法玩orz
2.不是DAG
好办,就分为可以作为起点的结点和不可以的两种情况输出
3.是DAG
加一个超级汇点,让这个汇点连接所有可以作为初始结点的结点,这样就转换成了单源最短路径问题,可以用Dijkstra解决。
但是注意这不是最朴素的Dijkstra
3.1 要记录每个结点的前置结点
然后用深度优先的方式递归输出路径
3.2 拥有第二标尺
完整代码如下(注:考试时没做出来,以下代码仅仅是通过了两个给出的test case)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1010;
const int inf = 1000000000;//即10^9
struct Node{
int v;//vertex
int s;//score
int d;//dollar
Node(int _v,int _s,int _d):v(_v),s(_s),d(_d){}
};
vector<Node> Adj[maxn];
int vNum,eNum,qNum,inDegree[maxn] = {0},isStart[maxn] = {0};
bool topologicalSort(){
queue<int> Q;
int num = 0;//入队的总结点数
for(int i=0;i<vNum;i++){
if(inDegree[i]==0){
Q.push(i);
isStart[i] = 1;//i是起始节点
}
}
while(!Q.empty()){
int v = Q.front();
Q.pop();
for(int i=0;i<Adj[v].size();i++){
int u = Adj[v][i].v;
inDegree[u] --;
if(inDegree[u]==0){
Q.push(u);
}
}
num ++;
// Adj[v].clear();
}
if(num==vNum)return true;
else return false;
}
int dis[maxn];
int vou[maxn];
int pre[maxn];
void Dijkstra(){
int s = vNum;
bool vis[maxn] = {0};
fill(dis,dis+vNum,inf);
dis[s] = 0;
fill(vou,vou+vNum,0);
for(int i=0;i<=vNum;i++){//每次点亮一个结点
//找当前未点亮结点中距离最近的
int v = -1,MIN = inf;
for(int j=0;j<=vNum;j++){//到这一步出现了段错误
if(vis[j]==false&&dis[j]<MIN){
MIN = dis[j];
v = j;
}
}
if(v==-1)return;
vis[v] = true;
for(int j=0;j<Adj[v].size();j++){
int u = Adj[v][j].v;
if(dis[u]>dis[v]+Adj[v][j].s&&vis[u]==false){
dis[u] = dis[v]+Adj[v][j].s;
vou[u] = vou[v]+Adj[v][j].d;
pre[u] = v;
}else if(dis[u]==dis[v]+Adj[v][j].s&&vou[u]<vou[v]+Adj[v][j].d&&vis[u]==false){
vou[u] = vou[v]+Adj[v][j].d;
pre[u] = v;
}
}
}
}
void DFS(int u){//s是起点,u是终点
if(u==vNum){
// printf("%d",u);
return;
}
DFS(pre[u]);
if(isStart[u]!=1)printf("->");
printf("%d",u);
}
int main(){
scanf("%d %d",&vNum,&eNum);
int v1,v2,s,d;
for(int i=0;i<eNum;i++){
scanf("%d %d %d %d",&v1,&v2,&s,&d);
inDegree[v2]++;
Node node = Node(v2,s,d);
Adj[v1].push_back(node);
}
bool tsSuccess = topologicalSort();//拓扑排序成功否
if(tsSuccess){
//增加一个点,编号为vNum,作为超级源点
for(int i=0;i<vNum;i++){
if(isStart[i]==1){
inDegree[i]++;
Node node = Node(i,0,0);
Adj[vNum].push_back(node);
}
}
printf("Okay.\\n");
Dijkstra();
scanf("%d",&qNum);
while(qNum--){
int u;//destination
scanf("%d",&u);
if(isStart[u]==1){
printf("You may take test %d directly.\\n",u);
}else{
DFS(u);
printf("\\n");
}
}
}else{
printf("Impossible.\\n");
scanf("%d",&qNum);
while(qNum--){
int u;
scanf("%d",&u);
if(isStart[u]==1)printf("You may take test %d directly.\\n",u);
else printf("Error.\\n");
}
}
return 0;
}
以上是关于PAT(甲级)2020年秋季考试 7-4 Professional Ability Test的主要内容,如果未能解决你的问题,请参考以下文章
PAT(甲级)2020年春季考试 7-4 Replacement Selection
PAT(甲级)2018年秋季考试 7-1 Werewolf - Simple Version