Link:
http://acm.hdu.edu.cn/showproblem.php?pid=2121
Topic:
Ice_cream ' s World II
Time limit:3000/1000 MS (java/others) Memory limit:32768/32768 K (java/others)
Total submission (s): 1610 accepted submission (s): 354
Problem Description
After awarded lands to Acmers, the Queen want to choose a is her capital. This is a important event in Ice_cream world, and it also a very difficult problem, because the world have N cities and M Roads, every road was directed. Wiskey is a chief engineer in Ice_cream World. The Queen asked Wiskey must find a suitable location to establish of the capital, beautify the roads which so capital can VI Sit each city and the project ' s cost as less as better. If Wiskey can ' t fulfill the Queen ' s require, he'll be punishing.
Input
Every case have two integers N and M (n<=1000, m<=10000), the cities numbered 0 ... N-1, following M lines, each line contain three integers S, T and C, the meaning from S to T have a road would cost C.
Output
If no location satisfy the Queen ' s require, you must to be output "impossible", otherwise, print the minimum cost in this pro Ject and suitable city ' s number. May is exist many suitable cities, choose the minimum number city. After every case print one blank.
Sample Input
3 1
0 1 1
4 4
0 1 10
0 2 10
1 3 20
2 3 30
Sample Output
Impossible 40 0
Author
Wiskey
Source
HDU 2007-10 Programming Contest_warmup
Recommend
Whiskey
Analysis and Summary:
More Wonderful content: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/
The problem of the minimum tree graph of adventitious roots, the solution is to design a "virtual new root", which starts at all points, and the weights are a great value (larger than the sum of the ownership values), and then find out if the node has a minimum tree graph.
The method of finding the real node is very ingenious, which utilizes the relationship between the position of the edge and the virtual node.
Code:
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> using namespace std
;
const int VN = 1005;
const int INF = 0x7fffffff;
int ans_root;
Template<typename type> class directed_mst{public:void init (int _n) {n=_n+1; size=0; ans=0;
} void Insert (int u, int v, Type _w) {e[size++].set (u,v,_w); Type directed_mst (int root) {while (true) {//1. Find the smallest precursor for (int i=1; i<n;
++i) In[i]=inf;
for (int i=0; i<size; ++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;
if (u==root) {ans_root = i;//Save the position of the edge I, not v}}
for (int i=1; i<n; ++i) if (i!=root) { if (In[i]==inf) return-1;
//2. Find ring int mxid = 1;
In[root] = 0;
memset (ID,-1, sizeof (ID));
memset (Vis,-1, sizeof (ID));
for (int i=1; i<n; ++i) {ans + = 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] = Mxid;
} Id[v] = mxid++; } if (mxid==1) break;
No loop for (int i=1; i<n; ++i) if (id[i]==-1) id[i] = mxid++;
3. Shrink point, re-mark for (int i=0; i<size; ++i) {int u=e[i].u, V=E[I].V; E[i]. u = id[u];
E[I].V = Id[v];
if (E[I].U!=E[I].V) E[I].W-= In[v];
} n = mxid;
root = Id[root];
return ans;
} private:struct edge{int u,v;
Type W;
void set (int _u,int _v,type _w) {u=_u,v=_v,w=_w;
}}E[VN*VN/2]; Type ans;
The answer Type IN[VN]; int n; The number of nodes int size; Number of sides int PRE[VN];
The precursor of the smallest weight value int id[vn]; int VIS[VN];
Whether it is in the ring or outside the ring;
directed_mst<int>g;
int main () {int n,m;
while (~SCANF ("%d%d", &n,&m)) {g.init (n+1);
int Max = 0;
for (int i=0; i<m; ++i) {int a,b;
int C;
scanf ("%d%d%d", &a,&b,&c);
if (a==b) continue;
Max + = C;
G.insert (A+1,B+1,C);
} ++max; Set n+1 to Virtual root node for (int i=m; i<m+n; ++i) {G.insert (n+1, i-m+1, Max); Note the relationship between the virtual node n+1 and I, after i>m, then from the virtual root node n+1 start//Reach 1,2,..., N. Use this relationship to use the location when I>m The relationship between fixed m+1 and other nodes//after this relationship output the root node} int ans = G.directed_ms
T (n+1);
if (Ans==-1 | | ans-max>=max) puts ("impossible");
else printf ("%d%d\n", Ans-max, ans_root-m);
Puts ("");
return 0; }
Author: csdn Blog shuangde800