Submission #1112788

#TimeUsernameProblemLanguageResultExecution timeMemory
1112788ThunnusSailing Race (CEOI12_race)C++17
100 / 100
951 ms6736 KiB
/*
    -We need 3 dp tables to figure out the answer:
    -dp1[l][r][a] - Max length of a path starting at l and ending at r, going in direction a.
    -dp2[l][r][a] - Max length of a path starting at l, visiting r and then continuing from r in the opposite direction(still in interval [l,r] and it can swap the direction multiple times)
    -dp3[l][r][a] - Max of dp2[l][l...r][a] : We need this to calculate the case where we have an intersection in O(n^3) and not O(n^4)
    -The case where there is no crossing can be solved using only the first 2 dps, the second case requires us to go though all the states of dp1, and for every one of them(if there is a path from l to r)
    we need to try to elongate it such that we only cross once at the starting segment(we first add a starting segment and then add an edge crossing it, followed by a path of maximal length from that edge to harbors not in the interval.
*/
#include <bits/stdc++.h>

using namespace std;

const int N=501;
bool adj[N][N];
int dp1[N][N][2],dp2[N][N][2],dp3[N][N][2],b[N][2];
pair<int,int> ans;
void calc(int l,int r,int a)
{
    if(adj[l][r])
    {
        dp1[l][r][a]=1;
        dp2[l][r][a]=1+dp3[r][b[l][a]][a^1];
    }
    else
    {
        dp1[l][r][a]=dp2[l][r][a]=INT_MIN/2;
    }
    for(int k=b[l][a];k!=r;k=b[k][a])
    {
        dp1[l][r][a]=max(dp1[l][r][a],dp1[l][k][a]+dp1[k][r][a]);
        dp2[l][r][a]=max(dp2[l][r][a],dp1[l][k][a]+dp2[k][r][a]);
    }
    dp3[l][r][a]=max(dp3[l][b[r][a^1]][a],dp2[l][r][a]);
}
int main()
{
	int n,k;
	scanf("%i %i",&n,&k);
	for(int i=0;i<n;i++)
    {
        int t;
        scanf("%i",&t);
        while(t!=0)
        {
            adj[i][t-1]=true;
            scanf("%i",&t);
        }
        b[i][0]=(i+1)%n;
        b[i][1]=(i-1+n)%n;
    }
    for(int l=1;l<n;l++)
        for(int i=0;i<n;i++)
            calc(i,(i+l)%n,0),calc((i+l)%n,i,1);
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int a=0;a<2;a++)
                ans=max(ans,make_pair(dp2[i][j][a],i));
    if(k)
    {
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                for(int a=0;a<2;a++)
                    if(dp1[i][j][a]>0)
                    {
                        int k=b[j][a];
                        for(;k!=i;k=b[k][a])
                            if(adj[k][i])
                                break;
                        if(k!=i)
                            for(int l=b[k][a];l!=i;l=b[l][a])
                                if(adj[j][l])
                                    ans=max(ans,make_pair(max(dp3[l][b[i][a^1]][a],dp3[l][b[k][a]][a^1])+dp1[i][j][a]+2,k));
                    }
    }
    printf("%i\n%i\n",ans.first,ans.second+1);
    return 0;
}
// :')

Compilation message (stderr)

race.cpp: In function 'int main()':
race.cpp:38:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   38 |  scanf("%i %i",&n,&k);
      |  ~~~~~^~~~~~~~~~~~~~~
race.cpp:42:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   42 |         scanf("%i",&t);
      |         ~~~~~^~~~~~~~~
race.cpp:46:18: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   46 |             scanf("%i",&t);
      |             ~~~~~^~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...