1. 程式人生 > >51nod 1445 變色DNA,最短路好題

51nod 1445 變色DNA,最短路好題

nbsp 最短 struct pro ble size retext targe 轉換成

1445 變色DNA技術分享 題目來源: TopCoder 基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級算法題 技術分享 收藏 技術分享 關註 技術分享 取消關註 有一只特別的狼,它在每個夜晚會進行變色,研究發現它可以變成N種顏色之一,將這些顏色標號為0,1,2...N-1。研究發現這只狼的基因中存在一個變色矩陣,記為colormap,如果colormap[i][j]=‘Y‘則這只狼可以在某一個夜晚從顏色i變成顏色j(一晚不可以變色多次),如果colormap[i][j]=‘N’則不能在一個晚上從i變成j色。進一步研究發現,這只狼每次變色並不是隨機變的,它有一定策略,在每個夜晚,如果它沒法改變它的顏色,那麽它就不變色,如果存在可改變的顏色,那它變為標號盡可能小的顏色(可以變色時它一定變色,哪怕變完後顏色標號比現在的大)。現在這只狼是顏色0,你想讓其變為顏色N-1,你有一項技術可以改變狼的一些基因,具體說你可以花費1的代價,將狼的變色矩陣中的某一個colormap[i][j]=‘Y‘改變成colormap[i][j]=‘N‘。問至少花費多少總代價改變狼的基因,讓狼按它的變色策略可以從顏色0經過若幹天的變色變成顏色N-1。如果一定不能變成N-1,則輸出-1.
Input
多組測試數據,第一行一個整數T,表示測試數據數量,1<=T<=5
每組測試數據有相同的結構構成:
每組數據第一行一個整數N,2<=N<=50。
之後有N行,每行N個字符,表示狼的變色矩陣,矩陣中只有‘Y’與‘N’兩種字符,第i行第j列的字符就是colormap[i][j]。
Output
每組數據一行輸出,即最小代價,無解時輸出-1。
Input示例
3
3
NYN
YNY
NNN
8
NNNNNNNY
NNNNYYYY
YNNNNYYN
NNNNNYYY
YYYNNNNN
YNYNYNYN
NYNYNYNY
YYYYYYYN
6
NYYYYN
YNYYYN
YYNYYN
YYYNYN
YYYYNN
YYYYYN
Output示例
1
0
-1

分析:這道題的關鍵是把題轉換成最短路模型.把求從0變色為n-1所需最小代價看作從求0出發到n-1的帶權最短路徑,從頂點i到頂點j的權值為輸入的領接矩陣
第i行中第j列前面所有的Y的數目.然後用迪傑特斯拉算法求最短路就可以了.

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;

const int maxv=55;
int vis[maxv];
int V; vector<int> g[maxv]; struct node { int num,dis; }; bool operator <(const node& n1,const node& n2) { return n1.dis<n2.dis; } int cost[maxv][maxv]; int d[maxv],dp[maxv]; void input() { char ch; char s[maxv]; scanf("%d",&V); memset(vis,0,sizeof(vis)); memset(dp,0,sizeof(d)); for(int i=0;i<V;i++) for(int j=0;j<V;j++) { cost[i][j]=(i==j)?0:INF; } for(int i=0;i<V;i++) { scanf("%s",s); for(int j=0;s[j]!=\0;j++) { ch=s[j]; if(ch==Y) { g[i].push_back(j); dp[j]=(j==0)?1:dp[j-1]+1; } else dp[j]=(j==0)?0:dp[j-1]; cost[i][j]=(j==0)?0:dp[j-1]; } } } int solve() { fill(d,d+V,INF); priority_queue<node> que; d[0]=0; que.push(node{0,0}); while(!que.empty()) { int x=que.top().num; que.pop(); for(int i=0;i<g[x].size();i++) { int u=x; int v=g[x][i]; if(d[v]>d[u]+cost[u][v]) { d[v]=d[u]+cost[u][v]; que.push(node{v,d[v]}); } } } return d[V-1]==INF?-1:d[V-1]; } int main() { int t; scanf("%d",&t); while(t--) { input(); printf("%d\n",solve()); for(int i=0;i<V;i++) g[i].clear(); } return 0; }

 

51nod 1445 變色DNA,最短路好題