- 得反向建图,正向建图,使用优先队列,在权值相同的情况下,不同的选择会对后续的结果产生影响,而反向建图,从结果出发则可以避免这个影响。
- 以后得习惯逆向思维,反向建图会解决很多问题
#include<bits/stdc++.h>
using namespace std;
int n,tot;
const int N=4e5+10;
int head[N],e[N],rd[N];
queue<int>rec;
struct Edge{
int u,v,next;
}E[N];
struct node{
int w,id;
bool operator < (const node& a) const {
return w>a.w;
}
};
priority_queue<node>q;
void add(int u,int v)
{
E[++tot].v=v;
E[tot].next=head[u];
head[u]=tot;
}
void solve()
{
for(int i=1;i<=n;++i){
if(!rd[i]){
q.push(node{e[i],i});
}
}
//int time=1;
node now;
while(!q.empty()){
now=q.top();
q.pop();
rec.push(now.id);
int u=now.id;
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
rd[v]--;
if(!rd[v]) q.push(node{e[v],v});
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i){
int d;
scanf("%d%d",&e[i],&d);
for(int j=0;j<d;++j){
int u;
scanf("%d",&u);
add(i,u);
rd[u]++;
}
}
solve();
int ans=0;
int time=n-1;
while(!rec.empty()){
ans=max(e[rec.front()]+time,ans);
//printf("%d\n",rec.front());
rec.pop();
time--;
}
printf("%d\n",ans);
return 0;
}
/*
6
2 2 4 3
4 1 5
1 2 2 4
4 1 5
2 0
4 1 3
*/
- 把圆分成1000份,因为最多只有1000个点,每个点后面有几个子孙,这个点就占圆的千分之几,dfs一遍就行了,队友最开始想的是把同一个圆上的点均分,太复杂了;
#include<bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
const int maxn = 1001;
pair<double,double>ans[maxn];
vector<int>g[maxn];
int n, siz[maxn];
void dfs (int u, int fa, double ang)
{
siz[u]++;
for (auto v : g[u]) {
if(v != fa) {
ans[v].first = ans[u].first + cos(ang);
ans[v].second = ans[u].second + sin(ang);
dfs(v,u,ang);
siz[u] += siz[v];
ang += pi / (double)(maxn) * (double)(siz[v]);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
//cin >> n;
scanf("%d",&n);
for ( int i = 0; i < n - 1 ; ++i ) {
int u, v;
//cin >> u >> v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,-1,0.0);
for ( int i = 1; i <= n; ++i ) printf("%.10f %.10f\n",ans[i].first,ans[i].second);
return 0;
}