题目链接:
http://community.topcoder.com/stat?c=problem_statement&pm=12142
题目大意:
有一只可以变色的狼,
给定矩阵,矩阵第i行j列的元素代表是否可以从颜色i直接变为颜色j,'Y'代表可以,'N'代表不可以。
每个时刻,狼将从它可以变的颜色中找一个序号最小的,变成那个颜色。
已知可以将矩阵中的某些'Y'变成'N'。
现有一只颜色为0的狼,
问至少要把矩阵中的多少个'Y'变成'N',才能让这只狼能够把颜色变为N-1。
算法:
这道题是很显然的SPFA模型。
计算的是0到N-1的最短路。
而所谓的距离是指,假设狼在x颜色时要变为y颜色,那么矩阵x行上所有纵坐标小于y的元素都要变为N,而且第y列的元素本来就要是'Y'。
所以dis[i][j] = mat[i][j] ? sum(dis[i][0], dis[i][1], ..., dis[i][j - 1]) : -1 (-1代表不可达)
求最短路即可。
代码:
#include <string>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <climits>
#include <cmath>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;
const int MAXN = 50;
int sum[MAXN][MAXN];
int d[MAXN];
queue <int> q;
class ColorfulWolves
{
public:
int getmin(vector <string> colormap)
{
int n = colormap.size();
memset(d, -1, sizeof(d));
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < n; j ++)
{
if(colormap[i][j] =='Y')
{
sum[i][j] = 1;
}
else
{
sum[i][j] = 0;
}
if(j)
{
sum[i][j] += sum[i][j - 1];
}
}
}
while(! q.empty())
{
q.pop();
}
d[n - 1] = 0;
q.push(n - 1);
while(! q.empty())
{
int u = q.front();
q.pop();
if(! u)
{
continue;
}
for(int i = 0; i < n; i ++)
{
if(colormap[i][u] == 'Y')
{
if(d[i] == -1 || d[i] > d[u] + sum[i][u - 1])
{
d[i] = d[u] + sum[i][u - 1];
q.push(i);
}
}
}
}
return d[0];
}
};