1. 程式人生 > 實用技巧 >10.17補題

10.17補題

因某些原因未能參加比賽,在賽後重新做了一遍,過的題就不寫補題了,寫兩個沒過的;

7-9 這題就是先預處理所有人的輩分,用dfs來處理每個人的輩分,一開始我沒在函式裡寫等於,在函式外面執行完在賦值,但是有一個點會超時,看了大佬的之後,就感覺和並查集find函式的簡化有點類似,程式碼:

超時一個點的

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int p[100005];
int ru[100005];
vector<int>ans;
int v;
int minn=0;
int solve(int n,int
m) { if(p[n]==-1)return m; if(ru[n]!=0) { // cout<<n<<" "<<ru[n]<<" "<<m<<endl; return m+ru[n]-1; } return solve(p[n],m+1); } int main() { cin>>v; for(int i=1;i<=v;i++) { cin>>p[i]; if
(p[i]==-1)continue; } for(int i=1;i<=v;i++) { int num=solve(i,1); ru[i]=num; // cout<<ru[i]<<endl; if(num>minn) { ans.clear(); ans.push_back(i); minn=num; } else if(num==minn)ans.push_back(i); } cout
<<minn<<endl; for(int i=0;i<ans.size();i++) { if(i==0) cout<<ans[i]; else cout<<" "<<ans[i]; } }
View Code

正確的:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int p[100005];
int ru[100005];
vector<int>ans;
int v;
int minn=0;
int solve(int n)
{
    if(ru[n]!=0)return ru[n];
    return ru[n]=solve(p[n])+1;
}
int main()
{
    
    cin>>v;
    for(int i=1;i<=v;i++)
    {
        cin>>p[i];
        if(p[i]==-1)ru[i]=1;
    }
    for(int i=1;i<=v;i++)
    {
        int num=solve(i);
        //cout<<ru[i]<<endl;
        if(ru[i]>minn)
        {
            minn=ru[i]; 
        }
    }
    for(int i=1;i<=v;i++)
    {
        if(ru[i]==minn)ans.push_back(i);
    }
    cout<<minn<<endl;
    for(int i=0;i<ans.size();i++)
    {
        if(i==0)
        cout<<ans[i];
        else
        cout<<" "<<ans[i];
        
    }
 } 
View Code

7-12 題,這題是找從某一個點進去最遠能到哪裡,這題起點沒說,是每一個點都能做起點,而且後來被經過的點都不會成為最遠的點,所以標記一下,在遇到就跳過,然後遍歷每個點,但是還是有一個點會超時,程式碼:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
vector<int>p[100005];
int ma=0,ans=1;
int vis[100005];
void solve(int v,int m)
{
    if(p[v].size()==0)
    {
        if(m>ma)
        {
            ma=m;
            ans=v;
        }
        return ;
    }
    for(int i=0;i<p[v].size();i++)
    {
        vis[p[v][i]]=1;
        solve(p[v][i],m+1);
    }
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int t;
        cin>>t;
        while(t--)
        {
            int b;
            scanf("%d",&b);
            p[i].push_back(b);
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(vis[i]==0)
        solve(i,0);
    }
    cout<<ans<<endl;
}
View Code

AC程式碼:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<double, double> PII;
const int maxn = 100000 + 15;
const int INF = 0x7fffffff;
const double eps = 1e-9;

int n;
int ceng[maxn];
vector<int> v[maxn];
set<int> s;

void dfs(int now, int x) {
    if (v[now].empty()) {
        ceng[now] = x;
        return;
    }
    if (ceng[now] > x)
        return;
    ceng[now] = x;
    for (auto i:v[now]) {
        dfs(i, x + 1);
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int k;
        cin >> k;
        for (int j = 1; j <= k; j++) {
            int t;
            cin >> t;
            s.insert(t);
            v[i].push_back(t);
        }
    }
    for (int i = 1; i <= n; i++)
        if (s.find(i) == s.end())
            dfs(i, 1);
    int ansM = 0, ansI;
    for (int i = 1; i <= n; i++)
        if (ansM < ceng[i]) {
            ansM = ceng[i];
            ansI = i;
        }
    cout << ansI << endl;
    return 0;
}
View Code