思路:有n个城市,m条单向道路,开始你在k号城市,现在要你从k开始出发,访问每个城市至少一次,就最少的花费,不行的话就impossible,这样看的话就是搜索了,,,但是题目中还给出了条件的,,,如果x号城市你之前访问过了的,那么你可以从你现在所在城市不花时间的瞬移到x号城市去。这样一来就不再是简单的搜索了,而是最小树形图了。
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
// #define DEBUG
#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__ )
#else
#define debug(...)
#endif
#define CLR(x) memset(x, 0,sizeof x)
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1010;
int in[maxn];
struct Edge{
int u, v, w;
}E[maxn << 4];
int pre[maxn], cnt, id[maxn], vis[maxn];
int root;
int n, m, k;
int solve(){
int sum = 0;
while(true){
memset(in, INF,sizeof in);
memset(pre, -1,sizeof pre);
for (int i = 0;i < cnt;++i){
int u = E[i].u, v = E[i].v;
if (E[i].w < in[v] && u != v){
pre[v] = u;
in[v] = E[i].w;
}
}
for (int i = 0;i < n;++i){
if (i == root) continue;
if (in[i] == INF) return -1;
}
int Num = 0;
memset(id, -1,sizeof id);
memset(vis, -1,sizeof vis);
in[root] = 0;
for (int i = 0;i < n;++i){
sum += in[i];
int v = i;
while(vis[v] != i && id[v] == -1 && v != root){
vis[v] = i;
v = pre[v];
}
if (v != root && id[v] == -1){
for (int u = pre[v];u != v;u = pre[u]){
id[u] = Num;
}
id[v] = Num++;
}
}
if (Num == 0) break;
for (int i = 0;i < n;++i)
if (id[i] == -1) id[i] = Num++;
for (int i = 0;i < cnt;++i){
int v = E[i].v;
E[i].u = id[E[i].u];
E[i].v = id[E[i].v];
if (E[i].u != E[i].v) E[i].w = E[i].w - in[v];
}
n = Num;
root = id[root];
}
return sum;
}
int main()
{ // ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t, icase = 0;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&k);
cnt = 0;
int u, v, c;
while(m--){
scanf("%d%d%d",&u,&v,&c);
E[cnt].u = u;E[cnt].v = v;E[cnt].w = c;
cnt++;
}
root = k;
int ans = solve();
if (ans == -1) printf("Case %d: impossible\n", ++icase);
else printf("Case %d: %d\n", ++icase, ans);
}
return 0;
}