F题考试成绩——拓扑排序
算法操作:
将入度为0的节点入队——把节点存入数组——然后删除以该节点为起始点的边(入度- -)
主要代码在快读之后
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define mem(a) memset(a,0,sizeof(a)) //
using namespace std;
const ll mx=500+5;
inline int read() {
int x=0,flag=1;
char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {x=x*10+c-'0';c=getchar();}
return x*flag;
}
int n,m,res[mx];
int G[mx][mx]; //邻表来存这个DAG
int indegree[mx]; //对箭头指向的点有一个入度统计
priority_queue<int,vector<int>,greater<int> > q;//用优先队列可以按大小顺序输出
void toposort() {
for(int i=1;i<=n;i++) {
if(indegree[i]==0) {q.push(i);} //入度为0的入队
}
int t=0;
while(!q.empty()) {
int temp=q.top();q.pop();
res[t++]=temp;
for(int i=1;i<=n;i++) {
if(G[temp][i]) {indegree[i]--;q.push(i); }//删去入度0节点所连的边
}
}
}
signed main() { //signed纯属装
while(scanf("%d %d",&n,&m)==2&&n) {
mem(G),mem(res),mem(indegree);
while(m--) {
int a=read(),b=read();
G[a][b]=1;
indegree[b]++; //入度加
}
toposort();
for(int i=0;i<n-1;i++)
printf("%d ",res[i]);
printf("%d\n",res[n-1]);
}
return 0;
}
H题修建道路
超级简单的并查集应用(当时居然没写粗)还是不熟练
搞懂了路径压缩用起来还是蛮顺手的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#define ll long long
#define ull unsigned long long
#define mem(a) memset(a,0,sizeof(a)) //
using namespace std;
const ll mx=500+5;
const double PI=acos(-1.0);
inline int read() {
int x=0,flag=1;
char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {x=x*10+c-'0';c=getchar();}
return x*flag;
}
struct team {
int u,v,w;
}a[10005];
int f[305];
bool cmp(team a,team b) {return a.w<b.w; }
int Find(int x) {return f[x]==x?x:f[x]=Find(f[x]); }
signed main() {
int n=read(),m=read();
for(int i=0;i<m;i++) {
a[i].u=read(),a[i].v=read(),a[i].w=read();
}
for(int i=1;i<=n;i++) f[i]=i;
sort(a,a+m,cmp);
int Max=0,tot=0;
for(int i=0;i<m;i++) {
int x=Find(a[i].u),y=Find(a[i].v);
if(x!=y) {f[x]=y;Max=max(Max,a[i].w);tot++; }
if(tot==n-1) break; //
}
printf("%d %d",n-1,Max);
return 0;
}
第一次用博客记录学习过程,希望能坚持下去