1.家谱树
寻寻有一个大家庭,辈分关系很混乱,请你帮他梳理一下家庭成员的关系。
输入:
第一行n,表示共5个人。
接下来的n行,第i行表示第i个人的孩子。
每行以0结束。
输出:
一行序列,空格隔开,使得每个人的后辈都比那个人后出现。
spj
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<queue> #include<cstdlib> #include<stack> using namespace std; int n,cnt,ru[10005],hd[10005],ans, x,t,y; stack<int> q; struct Edge{ int to, nxt; }edge[1000005]; void add(int u, int v){ cnt++; edge[cnt].to = v; edge[cnt].nxt = hd[u]; hd[u] = cnt; } int main(){ scanf("%d",&n); for(int i = 1; i <= n; i++){ while(~scanf("%d",&y)){ if(y == 0) break; add(i,y); ru[y]++; } } int mx = 0; for(int i = 1; i <= n; i++) if(ru[i] == 0){ q.push(i); } while(!q.empty()){ int u = q.top(); q.pop(); printf("%d ",u); for(int i = hd[u]; i; i = edge[i].nxt){ int v = edge[i].to; ru[v]--; if(!ru[v]){ q.push(v); } } } return 0; } /* 5 0 4 5 0 1 0 5 3 0
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<stack>
using namespace std;
int n,cnt,ru[10005],hd[10005],ans, x,t,y;
stack<int> q;
struct Edge{
int to, nxt;
}edge[1000005];
void add(int u, int v){
cnt++;
edge[cnt].to = v;
edge[cnt].nxt = hd[u];
hd[u] = cnt;
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d",&n);
for(int i = 1; i <= n; i++){
while(~scanf("%d",&y)){
if(y == 0) break;
add(i,y);
ru[y]++;
}
}
int mx = 0;
for(int i = 1; i <= n; i++)
if(ru[i] == 0){
q.push(i);
}
while(!q.empty()){
int u = q.top(); q.pop();
printf("%d ",u);
for(int i = hd[u]; i; i = edge[i].nxt){
int v = edge[i].to;
ru[v]--;
if(!ru[v]){
q.push(v);
}
}
}
return 0;
}
/*
5
0
4 5 0
1 0
5 3 0
3 0
*/
P1113 杂务
题解:递推关系
数据:
input:
10
1 3 0
2 9 1 0
3 2 1 2 0
4 2 1 2 3 0
5 12 2 0
6 1 1 2 3 4 5 0
7 17 3 0
8 7 1 2 3 4 5 6 7 0
9 13 1 3 8 0
10 2 1 2 3 4 5 6 7 8 9 0
output:
53
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<queue> #include<cstdlib> #include<stack> using namespace std; int n,cnt,at[10005],ru[10005],hd[10005],ans, x,t,y, f[10005]; stack<int> q; struct Edge{ int to, nxt; }edge[1000005]; void add(int u, int v){ cnt++; edge[cnt].to = v; edge[cnt].nxt = hd[u]; hd[u] = cnt; } int main(){ scanf("%d",&n); for(int i = 1; i <= n; i++){ scanf("%d%d",&x,&t); at[x] = t; while(~scanf("%d",&y)){ if(y == 0) break; add(y,x); ru[x]++; } } int mx = 0; for(int i = 1; i <= n; i++) if(ru[i] == 0){ q.push(i); f[i] = at[i]; } while(!q.empty()){ int u = q.top(); q.pop(); for(int i = hd[u]; i; i = edge[i].nxt){ int v = edge[i].to; ru[v]--; if(!ru[v]){ q.push(v); } f[v] = max(f[v], f[u] + at[v]); ans = max(ans, f[v]); } } printf("%d\n",ans); return 0; }
P1983 车站分级
P3074 [USACO13FEB]Milk Scheduling S
小X的N头奶牛要挤奶N∈[1,10000].为了方便编号1…N.每头奶牛挤奶耗时T[i] .但是有些奶牛一定要在另一头奶牛前挤奶。为了加快挤奶速度,小X雇佣了无限个农场工人。可以同时挤奶,求最少的时间挤完所有奶。
u1-v
u2-v
dis[v] = max(dis[u]+ dis[v](最开始的dis[v],否则两者会叠加,因此使用pre数组))
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int n, m, ru[N], chu[N], x, y, ans, hd[N], dis[N], cnt, pre[N];
queue<int> q;
struct Edge{
int to, nxt;
}edge[50005];
void add(int u, int v){
cnt++;
edge[cnt].nxt = hd[u];
edge[cnt].to = v;
hd[u] = cnt;
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
scanf("%d",&dis[i]); pre[i] = dis[i];
}
for(int i = 1; i <= m; i++){
scanf("%d%d",&x,&y);
add(x,y); ru[y]++; chu[x]++;
}
for(int i = 1; i <= n; i++){
if(!ru[i]){
q.push(i);
}
}
while(!q.empty()){
int u = q.front(); q.pop();
if(!chu[u]){
ans = max(ans, dis[u]);
}
for(int i = hd[u]; i; i = edge[i].nxt){
int v = edge[i].to; ru[v]--;
dis[v] = max(dis[v], dis[u] + pre[v]);
// cout<<"v: "<<v<<" "<<dis[v]<<endl;
if(ru[v] == 0)
// dis[v] = max(dis[v], dis[u] + dis[v]),
q.push(v);
}
}
printf("%d\n",ans);
return 0;
}
/**
10 10
1 2 3 4 5 6 7 8 9 10
3 4
5 4
5 10
4 6
4 10
10 1
6 1
6 2
1 8
9 7
*/