Cod sursa(job #2307848)

Utilizator shantih1Alex S Hill shantih1 Data 25 decembrie 2018 19:13:22
Problema Santa Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.96 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <deque>
#define nmx 45105

using namespace std;
ifstream fin("santa.in");
ofstream fout("santa.out");

int n,m,x,s,e,q,i,j,nr,pi,pf,nn,n1,sf,nrf;
int v[nmx],z[nmx],h[nmx],g[nmx][2],p[32800][20],l[20][20],drfin[nmx],drc[nmx],back[nmx];
vector<int> ad[nmx],no[nmx],ptr[32800];
deque<int> dq;
int crit(int nd,int p);
void search(int nd,int o);

void calcul(int st,int t)
{
	if(p[st][t])	return;
	int x=st-(1<<(t-1));
	
	for(int j:ptr[x])
		if(j>1 && l[t][j])
		{
			calcul(x, j);
			if(p[x][j])	
			{	p[st][t]=j;		return;		}
		}
}
void path()
{
	int i,j;
	for(i=1;i<=nn;i++)
		for(j=1;j<=nn;j++)	l[i][j]=0;
	for(i=1;i<=nn;i++)
		for(int k:ad[v[i]])
			l[i][h[k]]=1,   l[h[k]][i]=1;
	
	p[1][1]=0;
	for(i=2;i<=nn;i++)
		if(l[1][i])	p[1+(1<<(i-1))][i]=1;
	
	int x=(1<<nn)-1,y;
	if(sf)	calcul(x, sf);
	else 
		for(i=2;i<=nn;i++)
		{
			calcul(x, i);
			if(p[x][i])	sf=i, i=nn;
		}
	if(sf==0)	n1=100;
	
	nr=0;
	while(sf)
	{
		y=p[x][sf];
		drc[++nr]=v[sf];
		x-=(1<<(sf-1));
		sf=y;
	}
	for(i=nr;i>=1;i--)
		if(drc[i]!=drfin[nrf])	drfin[++nrf]=drc[i];
	
	for(i=(1<<nn)-1;i>=1;i--)
		for(int j:ptr[i])	p[i][j]=0;
}
int main() {
	
	fin>>n>>m;
	for(i=1;i<=m;i++)
	{
		fin>>s>>e;
		ad[s].push_back(e), ad[e].push_back(s);
	}
	fin>>s>>e>>q;
	
	h[1]=1;
	crit(1,0);
	
	search(s, 0);
	search(e, 1);
	
	for(i=1;i<=n;i++)
	{
		z[i]=0;
		if(g[i][0]!=g[i][1])	z[i]=++nn, back[nn]=i;
	}
	for(i=1;i<=n;i++)
		if(z[i])
			for(int j:ad[i])
				if(z[j])	no[z[i]].push_back(z[j]);
	n=nn;
	s=z[s], e=z[e], q=z[q];
	for(i=1;i<=n;i++)
	{
		while(!ad[i].empty())	ad[i].pop_back();
		for(int j:no[i])
			ad[i].push_back(j);
		z[i]=0;
		h[i]=0;
	}
	
	h[1]=1;
	crit(1, 0);
	for(i=1;i<=n;i++)	h[i]=0;
	
	for(i=1;i<=32768;i++)
		for(j=0;j<=15;j++)
			if(i&(1<<j))	ptr[i].push_back(j+1);
	
	if(z[q] || q==0)
	{	fout<<"No chance\n";	return 0;	}
	
	m=n-1;
	h[q]=1;
	v[nn=1]=q;
	dq.push_back(q);
	while(!dq.empty())
	{
		x=dq.front();
		dq.pop_front();

		if(z[x]==1 || m==0)
		{
			sf=h[x];
			if(m==0)	sf=0;
			path();
			
			if(n1>1)
			{	fout<<"No chance\n";	return 0;	}
			n1--;
			if(m==0)	m--;
			z[x]=0;
			v[nn=1]=x;
			h[x]=1;
			dq.push_back(x);
			continue;
		}
		
		for(int j:ad[x])
			if(h[j]==0)
			{
				h[j]=++nn, m--;
				v[nn]=j;
				if(z[j]==0)	dq.push_front(j);
				else	dq.push_back(j), n1++;
			}
	}
	
	fout<<nrf<<"\n";
	for(i=1;i<=nrf;i++)
		fout<<back[drfin[i]]<<" ";	fout<<"\n";
}

int crit(int nd,int p)
{
	h[nd]=h[p]+1;
	int mx=h[nd],f,nr=0;
	for(int j:ad[nd])
		if(j!=p)
		{
			if(h[j])	f=h[j];
			else
			{
				nr++;
				f=crit(j, nd);
				if(f>=h[nd])	z[nd]=1;
			}
			mx=min(mx,f);
		}
	if(nd==1 && nr==1)	z[1]=0;
	return mx;
}
void search(int nd,int o)
{
	int i,x,k;
	for(i=1;i<=n;i++)	h[i]=0;
	
	h[nd]=1;
	g[nd][o]=nd;
	dq.push_back(nd);
	while(!dq.empty())
	{
		x=dq.front();
		if(z[x]==1)	k=x;
		else	k=g[x][o];
		dq.pop_front();
		
		for(int j:ad[x])
			if(h[j]==0)
			{
				h[j]=1;
				g[j][o]=k;
				if(z[j]==0)	dq.push_front(j);
				else dq.push_back(j);
			}
	}
}