1. 程式人生 > >2015-2016 ACM-ICPC Southwestern Europe Regional Contest (SWERC 15) A題Promotions

2015-2016 ACM-ICPC Southwestern Europe Regional Contest (SWERC 15) A題Promotions

題目大意:給你一個DAG關於1(E-1)個數字,然後有一個[A,B]的區間,讓你給其中一些人升職,但是升職的前提是需要給他的上級升職,也就是說1->2意味著當你要給2升職的之前,先讓他的上級1升職,然後問的是,要想讓A個人升職時肯定要升職的人數是多少,讓B個人升職肯定升職的人數,然後再輸出給即使給B個人升職,也升職不到的人數有幾個

解題思路:要想算出肯定升值的人,肯定要找出來有多少人在升職之前需要先升職某個人,need[i]指的是升職之前需要先升職i的人人數,need[i]越大意味著他率先升職的位次越靠後,根據need就可以求出來,一個人升職之前不需要升職的人有多少個,稱之為noneed[i],

我們就可以根據noneed[i]越小意味著升職位置越靠前

對於求出誰肯定不升職來說就很簡單了,判斷一下該人升職前所需要升職的人數與B的關係即可

#include<iostream>    
#include<cstdio>  
#include<stdio.h>  
#include<cstring>    
#include<cstdio>    
#include<climits>    
#include<cmath>   
#include<vector>  
#include <bitset>  
#include<algorithm>    
#include <queue>  
#include<map>  
using namespace std;

vector<int> b[5005], a[5005];
queue<int> qua;
bool needs[5005][5005];
int noneed[5005], need[5005], flag[5005];
int A, B, E, P, j, k, ans, l, r, ss;
void dfs(int x, int y)
{
	for (int i = 0; i < b[x].size(); i++)
	{
		if (b[b[x][i]].size() != 0 && flag[b[x][i]] == 0)
		{
			flag[b[x][i]] = 1;
			dfs(b[x][i], y);
		}
		needs[y][b[x][i]] = true;
	}
}
int main()
{
	int x, y, i;
	cin >> A >> B >> E >> P;
	memset(needs, false, sizeof(needs));//needs[i][j]表示j是i的上級,i升職前需要先升職j
	memset(noneed, 0, sizeof(noneed));
	memset(need, 0, sizeof(need));
	for (i = 1; i <= P; i++)
	{
		cin >> x >> y;
		b[y].push_back(x);//x是y的上級
		needs[y][x] = true;//反向建圖
	}
	for (i = 0; i < E; i++)
	{
		memset(flag, 0, sizeof(flag));
		flag[i] = 1;
		dfs(i, i);//反向尋找所有與i點有關的上級
	}
	for (i = 0; i < E; i++)
	{
		for (j = 0; j < E; j++)
		{
			if (needs[i][j] != true && i != j)//needs[i][j]為flase意味著j升職與否與i沒有關係
			{
				noneed[j]++;//意味著計算有多少點不需要j升職後再升職
			}
			if (needs[i][j] == true)
			{
				need[i]++;//意味著有多少人要先於i點升職
			}
		}
	}
	l = 0;
	r = 0;
	ans = 0;
	for (i = 0; i < E; i++)
	{
		if (noneed[i] < A)//意味著i點與多少人沒有關係
		{
			l++;
		}
		if (noneed[i] < B)
		{
			r++;
		}
		if (need[i] >= B)//意味著如果在i點之前需要升職的人多於[A,B]的範圍,他將永遠沒辦法升職
		{
			ans++;
		}
	}
	cout << l << endl;
	cout << r << endl;
	cout << ans << endl;
}