ACM: uva 1424 - Salesmen

来源:互联网 发布:网络延迟多少ms算正常 编辑:程序博客网 时间:2024/06/06 02:58

Salesmen

Traveling salesmen of nhn. (theprestigious Korean internet company) report their current locationto the company on a regular basis. They also have to report theirnew location to the company if they are moving to another location.The company keep each salesman's working path on a map of hisworking area and uses this path information for the planning of thenext work of the salesman. The map of a salesman's working area isrepresented as a connected and undirected graph, where verticesrepresent the possible locations of the salesman an edgescorrespond to the possible movements between locations. Thereforethe salesman's working path can be denoted by a sequence ofvertices in the graph. Since each salesman reports his positionregularly an he can stay at some place for a very long time, thesame vertices of the graph can appear consecutively in his workingpath. Let a salesman's working pathbe correct if two consecutivevertices correspond either the same vertex or two adjacent verticesin the graph.

For example on the following graph representing theworking area of a salesman,

ACM: <wbr>uva <wbr>1424 <wbr>- <wbr>Salesmen

 

a reported working path [1 2 2 6 5 5 5 7 4] is acorrect path. But a reported working path [1 2 2 7 5 5 5 7 4] isnot a correct path since there is no edge in the graph betweenvertices 2 a 7. If we assume that the salesman reports his locationevery time when he has to report his location (but possiblyincorrectly), thenthe correct path could be [1 22 5 5 5 7 4], [12 7 5 5 5 7 4], or [1 22 5 5 5 7 4].

The length of a working path is the number ofvertices in the path. We definethe distance between twopaths A a1a2...an and B b1b2...bn ofthe same length n as

ACM: <wbr>uva <wbr>1424 <wbr>- <wbr>Salesmen

Given a graph representing the working area of asalesman and a working path (possible not a correctpath), A , of a salesman,write a program to compute a correct workingpath, B , of the samelength where thedistance dist(ABisminimized.

Input 

The program is to read the input from standardinput. The input consistsof T test cases. Thenumber of testcases (Tis given in thefirst line of the input. The first line of each test case containstwointegers n1 n2 (3n1 100, 2 n2 4,950) where n1 isthe number of vertices of the graph representing the working map ofa salesmanand n2 is thenumber of edges in the graph. The input graph is a connected graph.Each vertex of the graph is numbered from 1to n1 . In thefollowing n2lines, each linecontains a pair of vertices which represent an edge of the graph.The last line of each test case contains information on a workingpath of the salesman. The firstinteger n (2 n200) in the line is the length of the path and thefollowing n integers represent the sequence of vertices in theworking path.

Output 

Your program is to write to standard output. Printone line for each test case. The line should contain the minimumdistance of the input path to a correct path of the samelength.

SampleInput 

2

7 9

1 2

2 3

2 4

2 6

3 4

4 5

5 6

7 4

7 5

9 1 2 2 7 5 5 5 7 4

7 9

1 2

2 3

2 4

2 6

3 4

4 5

5 6

7 4

7 5

9 1 2 2 6 5 5 5 7 4

SampleOutput 

1

0

 

题意: 有出n个节点的无向图, 并且给出一段序列, 现在要求你修改最少的次数, 使得序列的任意相邻的两个

     数要么相同, 要么对应图中的两个相邻的点.

 

解题思路:

     1. 状态: dp[i][j]表示前i个并且第i个点选择更改为j的最少修改次数.

 

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 205
const int INF = (1<<29);

int n, m;
int g[MAX][MAX];
int num, a[MAX];
int dp[MAX][MAX];

inline int min(int a, int b)
{
 return a < b ? a : b;
}

int main()
{
// freopen("input.txt", "r", stdin);
 int caseNum, i, j;
 scanf("%d", &caseNum);
 while(caseNum--)
 {
  scanf("%d %d",&n, &m);
  memset(g, false,sizeof(g));
  int u, v;
  for(i = 1; i <=m; ++i)
  {
   scanf("%d%d", &u, &v);
   g[u][v] =true;
   g[v][u] =true;
  }

  for(i = 1; i<= n; ++i)
   g[i][i] =true;

  scanf("%d",&num);
  for(i = 1; i <=num; ++i)
   scanf("%d",&a[i]);

  for(i = 1; i<= n; ++i)
   dp[1][i] =1;
  
  dp[1][ a[1] ] = 0;
  for(i = 2; i <=num; ++i)
  {
   for(j = 1; j<= n; ++j)
    dp[i][j]= 1;
   dp[i][ a[i] ]= 0;
   for(j = 1; j<= n; ++j)
   {
    inttemp = INF;
    for(intk = 1; k <= n; ++k)
     if(g[j][k])temp = min(temp, dp[i-1][k]);
    dp[i][j]+= temp;
   }
  }

  int ans = INF;
  for(i = 1; i <=n; ++i)
   ans =min(ans, dp[num][i]);
  printf("%d\n", ans);
 }
 
 return 0;
}

0 0
原创粉丝点击