Cod sursa(job #541806)

Utilizator robigiirimias robert robigi Data 25 februarie 2011 14:35:28
Problema Lazy Scor 0
Compilator cpp Status done
Runda Romanian Master in Mathematics and Sciences 2011, Ziua 1 Marime 4.08 kb
#include <cstdio>
#include <bitset>

using namespace std;

FILE *f=fopen("lazy.in", "r");
FILE *g=fopen("lazy.out", "w");


typedef struct nod
{
	int x, pozi;
	long long c, c2;
	struct nod*adr;
};

nod *l[200001];

int n, m, nr, nnr;
long long heap[200001], he[200001];
int poz[200001], vpoz[200001];
bitset <200001> viz;
int muchii[200001], dl[200001];
long long inm[250];
long long inm2[250];
long long inm3[250], inm4[250];
int md;
long long sum;


void add(int x, int y, int c, int pozi, int c2)
{
	nod *p=new nod;
	p->x=y;
	p->pozi=pozi;
	p->c=c;
	p->c2=c2;
	p->adr=l[x];
	l[x]=p;
}


void read()
{
	fscanf(f, "%d%d", &n, &m);
	for (int i=1; i<=m; ++i)
	{
		int x, y;
		long long c, c2;
		fscanf(f, "%d%d%lld%lld", &x, &y, &c, &c2);
		add(x, y, c, i, c2);
		add(y, x, c, i, c2);
	}
}

int cmp(long long he1, long long heap1, long long he2, long long heap2)
{
	while (he1>0)
	{
		inm[++inm[0]]=he1%10;
		he1/=10;
		
	}
	for (int i=1; i<=inm[0]; ++i)
	{
		inm2[i]+=inm[i]*heap1%100000000;
		inm2[i+8]+=inm[i]*heap1/100000000;
	}
	while (inm2[inm2[0]+1]!=0)
	{
		inm2[0]++;
		inm2[inm2[0]+1]+=inm2[inm[0]]/10;
	}
	
	while (he2>0)
	{
		inm3[++inm3[0]]=he2%10;
		he2/=10;
		
	}
	for (int i=1; i<=inm[0]; ++i)
	{
		inm4[i]+=inm3[i]*heap2%100000000;
		inm4[i+8]+=inm3[i]*heap2/100000000;
	}
	while (inm4[inm4[0]+1]!=0)
	{
		inm4[0]++;
		inm4[inm4[0]+1]+=inm4[inm3[0]]/10;
	}
	
	if (inm2[0]>inm4[0])
		return 0;
	else
		while (inm2[inm2[0]]==inm4[inm2[0]] && inm2[0]>0)
			inm2[0]--;
	if (inm2[inm2[0]]>inm4[inm2[0]])
		return 0;
	
	return 1;
}


void upheap(int x)
{
	int fiu=x;
	int tata=x/2;
	while (fiu>1 && (heap[tata]>heap[fiu] || heap[fiu]==-1 || heap[tata]==heap[fiu] && cmp(he[tata], heap[tata], he[fiu], heap[fiu])==1))
	{
		long long h=heap[tata]; heap[tata]=heap[fiu]; heap[fiu]=h;
		h=he[tata]; he[tata]=he[fiu]; he[fiu]=h;
		h=poz[tata]; poz[tata]=poz[fiu]; poz[fiu]=h;
		h=muchii[tata]; muchii[tata]=muchii[fiu]; muchii[fiu]=h;
		vpoz[poz[tata]]=tata;
		vpoz[poz[fiu]]=fiu;
		fiu=tata;
		tata=fiu/2;
	}
}


void inheap(int x, int mm)
{
	++nnr;
	heap[nnr]=-1;
	he[nnr]=-1;
	poz[nnr]=x;
	muchii[nnr]=mm;
	vpoz[x]=nnr;
	upheap(nnr);
}


void inapm(int x)
{
	viz[x]=1;
	nod *p=l[x];
	while (p!=NULL)
	{
		if (!viz[p->x])
		{
			if (heap[vpoz[p->x]]>p->c || heap[vpoz[p->x]]==-1)
			{
				heap[vpoz[p->x]]=p->c;
				he[vpoz[p->x]]=p->c2;
				muchii[vpoz[p->x]]=p->pozi;
				upheap(vpoz[p->x]);
			}
			else
				if (heap[vpoz[p->x]]==p->c && cmp(he[vpoz[p->x]], heap[vpoz[p->x]], p->c, p->c2)==1)
				{
					heap[vpoz[p->x]]=p->c;
					he[vpoz[p->x]]=p->c2;
					muchii[vpoz[p->x]]=p->pozi;
					upheap(vpoz[p->x]);
				}
		}
		p=p->adr;
	}	
}



void initial()
{
	for (int i=2; i<=n; ++i)
		inheap(i, 1);
	inapm(1);
}


void downheap(int x)
{
	int tata=x;
	int fiu=tata*2;
	if (fiu+1<n-nr && (heap[fiu]>heap[fiu+1] || heap[fiu]==heap[fiu+1] && cmp(he[fiu], heap[fiu], he[fiu+1], heap[fiu+1])==1))
		++fiu;
	while ((heap[tata]>heap[fiu] || heap[tata]==heap[fiu] && cmp(he[tata], heap[tata], he[fiu], heap[fiu])==1) && fiu<n-nr)
	{
		long long h=heap[tata]; heap[tata]=heap[fiu]; heap[fiu]=h;
		h=he[tata]; he[tata]=he[fiu]; he[fiu]=h;
		h=poz[tata]; poz[tata]=poz[fiu]; poz[fiu]=h;
		h=muchii[tata]; muchii[tata]=muchii[fiu]; muchii[fiu]=h;
		vpoz[poz[tata]]=tata;
		vpoz[poz[fiu]]=fiu;
		tata=fiu;
		fiu=tata*2;
		if (fiu+1<n-nr && (heap[fiu]>heap[fiu+1] || heap[fiu]==heap[fiu+1] && cmp(he[fiu], heap[fiu], he[fiu+1], heap[fiu+1])==1))
			++fiu;
	}
}


int extragemin(int &aux)
{
	dl[++md]=muchii[1];
	muchii[1]=muchii[n-nr];
	aux=poz[1];
	int cv=heap[1];
	heap[1]=heap[n-nr];
	he[1]=he[n-nr];
	poz[1]=poz[n-nr];
	vpoz[poz[1]]=1;
	poz[n-nr]=0;
	heap[n-nr]=0;
	he[n-nr]=0;
	downheap(1);
	return cv;
}



void program()
{
	for (int i=1; i<n; ++i)
	{
		int aux;
		++nr;
		sum+=extragemin(aux);
		inapm(aux);
	}
	for (int j=1; j<=md; ++j)
	{
		fprintf(g, "%d\n", dl[j]);
	}
}


int main()
{
	read();
	initial();
	program();
	return 0;
}