Pagini recente » Cod sursa (job #1642644) | Cod sursa (job #2714110) | Cod sursa (job #2921148) | Cod sursa (job #195876) | Cod sursa (job #2490552)
#pragma GCC optimize("Ofast") /// nu stiu cum se foloseste asta dar m am saturat sa iau tle
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <fstream>
#include <vector>
#include <deque>
#define DIM 2010
#define INF 2000000000
using namespace std;
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
vector <int> L[DIM],edges[DIM];
deque <int> c;
int capacitate[DIM][DIM],cap[DIM][DIM],f[DIM][DIM],dist[DIM];
int n,k,i,j,nr1,sursa,dest,nr,x;
void bfs (int sursa, int dest){
for (int i=sursa;i<=dest;++i){
edges[i].clear();
dist[i] = INF;
}
c.clear();
c.push_back(sursa);
dist[sursa] = 0;
while (!c.empty()){
int nod = c.front();
c.pop_front();
if (nod == dest)
break;
for (int i=0;i<L[nod].size();++i){
int vecin = L[nod][i];
if (!capacitate[nod][vecin])
continue;
if (dist[vecin] == INF){
dist[vecin] = 1+dist[nod];
c.push_back(vecin);
}
if (dist[vecin] == 1+dist[nod])
edges[nod].push_back(vecin);
}}}
int dfs (int nod, int dest, int max_flow){
if (nod == dest || !max_flow)
return max_flow;
int flow = 0;
for (int i=0;i<edges[nod].size();++i){
int vecin = edges[nod][i];
if (!capacitate[nod][vecin])
continue;
int val = dfs (vecin,dest,min(capacitate[nod][vecin],max_flow-flow));
flow += val;
capacitate[nod][vecin] -= val;
capacitate[vecin][nod] += val;
}
return flow;
}
int verif (int val){
/// capacitatile
for (int i=sursa;i<=dest;++i)
for (int j=sursa;j<=dest;++j)
capacitate[i][j] = cap[i][j];
for (int i=k+2;i<=k+n;i++)
capacitate[i][dest] = val;
/// acum bagam flux
int sol = 0, flux = 0;
do{
bfs (sursa,dest);
flux = dfs (sursa,dest,INF);
sol += flux;
} while (flux);
if (sol == k-nr1)
return 1;
return 0;
}
int main (){
InParser fin ("necromancer.in");
ofstream fout ("necromancer.out");
fin>>k>>n;
/// n candidati si k cetateni
/// muchie intre sursa si cetateni
sursa = 0, dest = n+k+1;
for (i=1;i<=k;++i){
L[sursa].push_back(i);
L[i].push_back(sursa);
cap[sursa][i] = 1;
}
for (i=1;i<=k;++i){
fin>>nr;
for (j=1;j<=nr;++j){
fin>>x;
if (j > 1) /// x nu poate fi pus pe primul loc
f[i][x] = 1;
}
if (!f[i][1]) /// pot sa l fixez pe 1 primul
nr1++;
else {
for (j=2;j<=n;++j){
L[i].push_back(k+j);
L[k+j].push_back(i);
if (!f[i][j])
cap[i][k+j] = 1;
}}}
if (nr1 > k/2){
fout<<0;
return 0;
}
for (i=1+k;i<=n+k;++i){
L[i].push_back(dest);
L[dest].push_back(i);
}
/// incerc sa fixez o limita superioara de voturi pt fiecare candidat => o caut binar
/// vr sa gasesc cel mai mic nr de voturi pe care il pot avea toti concurentii
int st = 0, dr = k-nr1, sol = 0;
while (st <= dr){
int mid = (st+dr)>>1;
if (verif(mid)){
dr = mid-1;
sol = mid;
} else st = mid+1;
}
fout<<sol-nr1+1;
return 0;
}