Cod sursa(job #9497)

Utilizator scapryConstantin Berzan scapry Data 27 ianuarie 2007 15:52:46
Problema Amenzi Scor 90
Compilator cpp Status done
Runda Unirea 2007, clasele 11-12 Marime 1.96 kb
#include <stdio.h>

enum { maxn = 151, maxt = 3501 };

int n;
int graph[maxn][maxn];
int fine[maxn][maxt];
int dp[maxn][maxt];

void floyd_warshall()
{
        int i, j, k;
        
        for(i = 0; i < n; i++)
        	for(j = 0; j < n; j++)
        		if(!graph[i][j]) graph[i][j] = 0x1FFFFFF; //big enough
        
        for(k = 0; k < n; k++) //intermediate
                for(i = 0; i < n; i++)
                        for(j = 0; j < n; j++)
                                if(graph[i][k] + graph[k][j] < graph[i][j])
                                        graph[i][j] = graph[i][k] + graph[k][j];
}

void actually_burn(int start, int stop)
{
	int i, j, k;
	
	//dp
	for(i = start; i <= stop; i++) //time
	{
		for(j = 0; j < n; j++) //node
		{
			if(i < graph[0][j]) //can't get here in time
				dp[j][i] = -1; //worse than anything
			else
			{
				dp[j][i] = dp[j][i - 1];
				
				for(k = 0; k < n; k++)
				{
					if(k == j) continue;
					
					if(i - graph[j][k] >= 0) //valid time
						if(dp[k][ i - graph[j][k] ] > dp[j][i])
							dp[j][i] = dp[k][ i - graph[j][k] ];
				}
				
				dp[j][i] += fine[j][i];
			}
		}
	}
}

inline void burn(int stop)
{
	static int stopped = 0;
	
	if(stop <= stopped) return;
	else actually_burn(stopped + 1, stop);
	
	stopped = stop;
}

int main()
{
	int i, j, a, b, c, edges, tests, fines;
	FILE *fi = fopen("amenzi.in", "r"),
	     *fo = fopen("amenzi.out", "w");
	
	if(!fi || !fo) return 1;
	
	fscanf(fi, "%d%d%d%d", &n, &edges, &fines, &tests);
	
	for(i = 0; i < edges; i++)
	{
		fscanf(fi, "%d%d%d", &a, &b, &c);
		graph[a - 1][b - 1] += c;
		graph[b - 1][a - 1] += c;
	}
	
	for(i = 0; i < fines; i++)
	{
		fscanf(fi, "%d%d%d", &a, &b, &c);
		fine[a - 1][b] += c;
	}
	
	//get ready to burn
	floyd_warshall();
	dp[0][0] = 0; //fair
	for(j = 1; j < n; j++)
		dp[j][0] = -1; //worse than anything
	
	for(i = 0; i < tests; i++)
	{
		fscanf(fi, "%d%d", &a, &b);
		
		burn(b);
		
		fprintf(fo, "%d\n", dp[a - 1][b]);
	}
	
	fclose(fi);
	fclose(fo);
	return 0;
}