Week7 C-TT's dream

Title description

This night, TT had a sweet dream!

In his dream, TT's wish came true, and he became the leader of Meow Star! There are N commercial cities on the Meow Star, numbered 1 to N, of which City 1 is the city where TT is located, that is, the capital.

There are M directional roads on Meow Star for commercial cities to communicate with each other. However, with the increasing prosperity of Meowstar's business, some roads have become very crowded. While TT was distressed, his magic kitty came up with a solution! TT is pleased to accept and promulgate a new policy for this program.

The specific policy is as follows: mark a positive integer for each commercial city to indicate its prosperity. When each cat walks from one commercial city to another commercial city along the road, TT will charge them (destination prosperity-departure point) Prosperity) ^ 3 tax.

TT intends to test whether this policy is reasonable, so he wants to know how much tax must be paid to travel from the capital to other cities. If the total amount is less than 3 or cannot be reached, please quietly type '?'.
Input
T in the first line, indicating that there are T sets of data. (1 <= T <= 50)

For each set of data, enter N in the first row to indicate the number of points. (1 <= N <= 200)

Enter N integers in the second line, which represents the weight a [i] from 1 to N points. (0 <= a [i] <= 20)

Enter M in the third line to indicate the number of directional roads. (0 <= M <= 100000)

In the next M rows, each row has two integers AB, indicating that there is a directed road from A to B.

Next, an integer Q is given, indicating the number of inquiries. (0 <= Q <= 100000)

Each inquiry gives a P, which means seeking the minimum tax from point 1 to point P.
Output
Each query outputs one line. If it is unreachable or if the tax is less than 3, output '?'.
Sample Input

2
5
6 7 8 9 10
6
1 2
2 3
3 4
1 5
5 4
4 5
2
4
5
10
1 2 4 4 5 6 7 8 9 10
10
1 2
2 3
3 1
1 4
4 5
5 6
6 7
7 8
8 9
9 10
2
3 10

Sample Output

Case 1:
3
4

Case 2:
?
?

Ideas

This question uses the chain forward star to save the graph, and then uses the SPFA algorithm to find the shortest path. The SPFA algorithm:
1. Open a queue and put the starting node first.
2. Take a node X from the queue each time, traverse the Y node communicating with X, and query the length of Y and the length of X + the length of X and Y if the length of X + the length of X and Y> the length of Y , Indicating that the update operation is required:
1). Deposit the shortest path.
2). Since the original length is changed, it needs to be updated later, and the shortest path connected to this node. (That is: judge whether it is in the queue, whether it is in the negative ring, do not need to repeat it, join the queue if it is not, and wait for the update).
3). During this period, you can record the number of times this node has entered the team and determine whether there is a negative ring. After the number of times is greater than n, use dfs to traverse all the available points and record the vis array, indicating that they are in the negative ring
4. Until the team is empty.
If it is unreachable or less than three or in the negative ring, dis [p] == inf || dis [p] <3 || (vis [p] == 1)) output the answer? , Otherwise output dis [i]

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int inf = 100000;
struct edge
{
  int to,w,next;
}e[100005];

queue<int>q;

int head[205],a[205],dis[205],inq[205],vis[205],cnt[205];
int T,N,M,t1,t2,tot,Q,num=1;
void add(int s,int d)
{
    e[++tot].to=d, e[tot].w=(a[d]-a[s])*(a[d]-a[s])*(a[d]-a[s]);
    e[tot].next=head[s];
    head[s]=tot;
} 
void ini()
{
    tot=0;
    for(int i=0;i<=N;i++)
    {
        head[i]=-1;
        cnt[i]=inq[i]=vis[i]=0;
        dis[i]=inf;
        
    }
}
void dfs(int v)
{
    vis[v]=1;
    for (edge t = e[head[v]];head[v]!=-1; t = e[t.next])
     {
        if(vis[t.to]==0)dfs(t.to); 
        if(t.next==-1)break;
    }		
}
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        
        scanf("%d",&N);
        ini();
        for(int i=1;i<=N;i++)
        {
            scanf("%d",&a[i]);
        }
        scanf("%d",&M);
        for(int i=1;i<=M;i++)
        {
            scanf("%d%d",&t1,&t2);
            add(t1,t2);
        }
    
    
        dis[1] = 0;
		inq[1] = 1;
		q.push(1);
		while (!q.empty())
		{
			int u = q.front(); q.pop();
			inq[u] = 0;
			if (vis[u])continue;
           	 	if(head[u]==-1)continue;//不存在出边
			for (edge t = e[head[u]];; t = e[t.next])
               		{ 
				int v = t.to;
				//if (vis[v])continue;
				if (dis[v] > dis[u] + t.w) 
                		{
					cnt[v] = cnt[u] + 1;
					if (cnt[v] >= N) 
					{
						//找到负环
						dfs(v);							
					}					
					dis[v] = dis[u] + t.w;
					//pre[v] = u;
					if (!inq[v]) 
                    			{
						q.push(v);
						inq[v] = 1;						
					}
				}
				if (t.next == -1)break;
			}

		}
         	int p;
		scanf("%d",&Q);
		printf("Case %d:\n", num++);
		while (Q--) {
			cin >> p;
			if (dis[p] == inf || dis[p] < 3|| (vis[p]==1))printf("?\n");
			else printf("%d\n", dis[p]);
		} 
	 
    }
 //   system("pause");
    return 0;
}
Published 20 original articles · praised 3 · visits 447

Guess you like

Origin blog.csdn.net/qq_44893580/article/details/105569190