#include <bits/stdc++.h>
using namespace std;
int losuj(int a, int b)
{
long long pom=rand();
pom*=rand();
return pom%(b-a+1)+a;
}
int dp[3002], dptyl[3002], wyntyl[3002][5];
int block[3002];
const int odstep=1;
pair<int, int> wej[1002];
vector<int> kra[3002];
vector<int> trans[3002];
int best, n, licz=0, bclicz=0;
int licz_wyn()
{
int res=0;
for (int i=1; i<=n; i++)
{
dp[i]=1;
if (block[i]==1)
{
dp[i]=-100000000;
continue;
}
for (int j=0; j<trans[i].size(); j++)
{
dp[i]=max(dp[i], dp[trans[i][j]]+1);
}
res=max(res, dp[i]);
}
return res;
}
int stalazachlannosci=1, staph=70000000, minusik=2;///uwaga, poprawic staph jak trzeba!!!
///stala zachlannosci kontra best -2/-3
void backtrack(int k, int start, int mm)
{
//assert(bclicz<staph);
if (k==-1)// || bclicz>staph)
{
return;
}
int maksik=mm;
for (int i=start+odstep; i<=n; i++)
{
//bclicz++;
dp[i]=1;
//if (block[i]==1)
// continue;
for (int j=0; j<trans[i].size(); j++)
{
//licz++;
if (block[trans[i][j]]==1)
continue;
dp[i]=max(dp[i], dp[trans[i][j]]+1);
}
block[i]=1;
if (dp[i]>stalazachlannosci && (dp[i]>best-minusik || kra[i].size()>1))
backtrack(k-1, i, maksik);
block[i]=0;
maksik=max(maksik, dp[i]);
if (maksik>=best)
return;
}
best=min(best, maksik);
}
int main()
{
///dla k<=2 lub n<=105 jest ok, dziala szybko
ios_base::sync_with_stdio(0);
cin.tie(0);
srand(1337);
int m, k;
cin >> n >> m >> k;
best=n;
if (k<=2 || n<=75)
{
stalazachlannosci=-1;
minusik=1001;
}
//if (k<=3 || n<=250) ///do doprecyzowania!!!
// stalazachlannosci=1;
for (int i=0; i<m; i++)
{
int a, b;
cin >> a >> b;
wej[i]={a, b};
a=n-a+1;
b=n-b+1;
trans[a].push_back(b);
kra[b].push_back(a);
}
for (int ii=0; ii<30000; ii++)
{
int usun[4];
for (int i=0; i<k; i++)
{
int a=losuj(1, n);
block[a]=1;
usun[i]=a;
}
best=min(licz_wyn(), best);
for (int i=0; i<k; i++)
{
int a=usun[i];
block[a]=0;
}
}
//int pom=best;
//cout << best << "\n";
backtrack(k, 0, 0);
for (int i=1; i<=n; i++)
{
kra[i].clear();
trans[i].clear();
}
for (int i=0; i<m; i++)
{
kra[wej[i].first].push_back(wej[i].second);
trans[wej[i].second].push_back(wej[i].first);
}
backtrack(k, 0, 0);
//assert(best>=pom-2);
//cout << pom << "\n";
cout << best << "\n";
//cout << licz << " - licz\n";
//cout << bclicz << " - bclicz\n";
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #include <bits/stdc++.h> using namespace std; int losuj(int a, int b) { long long pom=rand(); pom*=rand(); return pom%(b-a+1)+a; } int dp[3002], dptyl[3002], wyntyl[3002][5]; int block[3002]; const int odstep=1; pair<int, int> wej[1002]; vector<int> kra[3002]; vector<int> trans[3002]; int best, n, licz=0, bclicz=0; int licz_wyn() { int res=0; for (int i=1; i<=n; i++) { dp[i]=1; if (block[i]==1) { dp[i]=-100000000; continue; } for (int j=0; j<trans[i].size(); j++) { dp[i]=max(dp[i], dp[trans[i][j]]+1); } res=max(res, dp[i]); } return res; } int stalazachlannosci=1, staph=70000000, minusik=2;///uwaga, poprawic staph jak trzeba!!! ///stala zachlannosci kontra best -2/-3 void backtrack(int k, int start, int mm) { //assert(bclicz<staph); if (k==-1)// || bclicz>staph) { return; } int maksik=mm; for (int i=start+odstep; i<=n; i++) { //bclicz++; dp[i]=1; //if (block[i]==1) // continue; for (int j=0; j<trans[i].size(); j++) { //licz++; if (block[trans[i][j]]==1) continue; dp[i]=max(dp[i], dp[trans[i][j]]+1); } block[i]=1; if (dp[i]>stalazachlannosci && (dp[i]>best-minusik || kra[i].size()>1)) backtrack(k-1, i, maksik); block[i]=0; maksik=max(maksik, dp[i]); if (maksik>=best) return; } best=min(best, maksik); } int main() { ///dla k<=2 lub n<=105 jest ok, dziala szybko ios_base::sync_with_stdio(0); cin.tie(0); srand(1337); int m, k; cin >> n >> m >> k; best=n; if (k<=2 || n<=75) { stalazachlannosci=-1; minusik=1001; } //if (k<=3 || n<=250) ///do doprecyzowania!!! // stalazachlannosci=1; for (int i=0; i<m; i++) { int a, b; cin >> a >> b; wej[i]={a, b}; a=n-a+1; b=n-b+1; trans[a].push_back(b); kra[b].push_back(a); } for (int ii=0; ii<30000; ii++) { int usun[4]; for (int i=0; i<k; i++) { int a=losuj(1, n); block[a]=1; usun[i]=a; } best=min(licz_wyn(), best); for (int i=0; i<k; i++) { int a=usun[i]; block[a]=0; } } //int pom=best; //cout << best << "\n"; backtrack(k, 0, 0); for (int i=1; i<=n; i++) { kra[i].clear(); trans[i].clear(); } for (int i=0; i<m; i++) { kra[wej[i].first].push_back(wej[i].second); trans[wej[i].second].push_back(wej[i].first); } backtrack(k, 0, 0); //assert(best>=pom-2); //cout << pom << "\n"; cout << best << "\n"; //cout << licz << " - licz\n"; //cout << bclicz << " - bclicz\n"; } |
English