NOIP模拟题 通讯 强连通分量缩点 最小树形图--朱刘算法
2017-09-02 15:54
393 查看
通讯
(message.cpp\c\pas)
【问题描述】
“这一切都是命运石之门的选择。”
试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短信,并由此得知了伦太郎制作出了电话微波炉(仮)。
为了掌握时间机器的技术,SERN总部必须尽快将这个消息通过地下秘密通讯网络,传达到所有分部。
SERN共有N个部门(总部编号为0),通讯网络有M条单向通讯线路,每条线路有一个固定的通讯花费Ci。
为了保密,消息的传递只能按照固定的方式进行:从一个已知消息的部门向另一个与它有线路的部门传递(可能存在多条通信线路)。我们定义总费用为所有部门传递消息的费用和。
幸运的是,如果两个部门可以直接或间接地相互传递消息(即能按照上述方法将信息由X传递到Y,同时能由Y传递到X),我们就可以忽略它们之间的花费。
由于资金问题(预算都花在粒子对撞机上了),SERN总部的工程师希望知道,达到目标的最小花费是多少。
【输入格式】
多组数据,文件以2个0结尾。
每组数据第一行,一个整数N,表示有N个包括总部的部门(从0开始编号)。然后是一个整数M,表示有M条单向通讯线路。
接下来M行,每行三个整数,Xi,Yi,Ci,表示第i条线路从Xi连向Yi,花费为Ci。
【输出格式】
每组数据一行,一个整数表示达到目标的最小花费。
【输入输出样例】
message.in
3 3
0 1 100
1 2 50
0 2 100
3 3
0 1 100
1 2 50
2 1 100
2 2
0 1 50
0 1 100
0 0
message.out
150
100
50
【样例解释】
第一组数据:总部把消息传给分部1,分部1再传给分部2.总费用:100+50=150.
第二组数据:总部把消息传给分部1,由于分部1和分部2可以互相传递消息,所以分部1可以无费用把消息传给2.总费用:100+0=100.
第三组数据:总部把消息传给分部1,最小费用为50.总费用:50.
【数据范围】
对于10%的数据,保证M=N-1
对于另30%的数据,N ≤ 20 ,M ≤ 20
对于100%的数据,N ≤ 50000 ,M ≤ 10^5 ,Ci ≤ 10^5 ,数据组数 ≤ 5
数据保证一定可以将信息传递到所有部门。
理论复杂度会T,还是踩标程,没办法(微笑)
(message.cpp\c\pas)
【问题描述】
“这一切都是命运石之门的选择。”
试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短信,并由此得知了伦太郎制作出了电话微波炉(仮)。
为了掌握时间机器的技术,SERN总部必须尽快将这个消息通过地下秘密通讯网络,传达到所有分部。
SERN共有N个部门(总部编号为0),通讯网络有M条单向通讯线路,每条线路有一个固定的通讯花费Ci。
为了保密,消息的传递只能按照固定的方式进行:从一个已知消息的部门向另一个与它有线路的部门传递(可能存在多条通信线路)。我们定义总费用为所有部门传递消息的费用和。
幸运的是,如果两个部门可以直接或间接地相互传递消息(即能按照上述方法将信息由X传递到Y,同时能由Y传递到X),我们就可以忽略它们之间的花费。
由于资金问题(预算都花在粒子对撞机上了),SERN总部的工程师希望知道,达到目标的最小花费是多少。
【输入格式】
多组数据,文件以2个0结尾。
每组数据第一行,一个整数N,表示有N个包括总部的部门(从0开始编号)。然后是一个整数M,表示有M条单向通讯线路。
接下来M行,每行三个整数,Xi,Yi,Ci,表示第i条线路从Xi连向Yi,花费为Ci。
【输出格式】
每组数据一行,一个整数表示达到目标的最小花费。
【输入输出样例】
message.in
3 3
0 1 100
1 2 50
0 2 100
3 3
0 1 100
1 2 50
2 1 100
2 2
0 1 50
0 1 100
0 0
message.out
150
100
50
【样例解释】
第一组数据:总部把消息传给分部1,分部1再传给分部2.总费用:100+50=150.
第二组数据:总部把消息传给分部1,由于分部1和分部2可以互相传递消息,所以分部1可以无费用把消息传给2.总费用:100+0=100.
第三组数据:总部把消息传给分部1,最小费用为50.总费用:50.
【数据范围】
对于10%的数据,保证M=N-1
对于另30%的数据,N ≤ 20 ,M ≤ 20
对于100%的数据,N ≤ 50000 ,M ≤ 10^5 ,Ci ≤ 10^5 ,数据组数 ≤ 5
数据保证一定可以将信息传递到所有部门。
讲道理,觉得题目性质太明显了,直接做就好了,可是这样太没意思了
于是就写了朱刘算法# include <cctype> # include <cstdio> # include <cstring> char buf [1 << 24], *ss, *tt ; inline char pick ( ) { if ( ss == tt ) { tt = buf + fread ( ss = buf, 1, 1 << 24, stdin ) ; if ( ss == tt ) return -1 ; } return *ss ++ ; } inline int read ( ) { register int x ; register char c ; while ( ! isdigit ( c = pick ( ) ) ) ; for ( x = -48 + c ; isdigit ( c = pick ( ) ) && ( c != -1 ) ; x= x * 10 + c - 48 ) ; return x ; } const int N = 50005 ; int in , id , pre , vis ; struct Edge { int u, v, c ; } e [N << 1] ; int qcnt ; inline int Zhuliu_algorithm ( int root, int n, int m, Edge* g ) { int rt ( 0 ) ; register int i, u, v ; for ( ; ; ) { memset ( in, 0x3f, sizeof ( int ) * ( n + 1 ) ) ; for ( i = 1 ; i <= m ; ++ i ) { u = g [i].u, v = g [i].v ; if ( g [i].c < in [v] && ( u ^ v ) ) { in [v] = g [i].c ; pre [v] = u ; } } for ( i = 1 ; i <= n ; ++ i ) { if ( i == root ) continue ; if ( in [i] == 0x3f3f3f3f ) return -1 ; } int cnt ( 0 ) ; memset ( id, -1, sizeof ( int ) * ( n + 1 ) ) ; memset ( vis, -1, sizeof ( int ) * ( n + 1 ) ) ; in [root] = 0 ; for ( i = 1 ; i <= n ; ++ i ) { rt += 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 ( u = pre [v] ; u != v; u = pre [u] ) id [u] = cnt ; id [v] = ++ cnt ; } } if ( cnt == 0 ) return rt ; //break ; for ( i = 1 ; i <= n ; ++ i ) if ( id [i] == -1 ) id [i] = ++ cnt ; for ( i = 1 ; i <= m ; ++ i ) { v = g [i].v ; g [i].v = id [g [i].v] ; g [i].u = id [g [i].u] ; if ( g [i].u ^ g [i].v ) { g [i].c -= in [v] ; } } n = cnt ; root = id [root] ; } // return rt ; } struct edge { int to, nxt, w ; } g [N << 1] ; int ecnt, head ; int stk , top ; int dfn , low , place , scnt, idx ; inline void Dfs ( int u ) { dfn [u] = low [u] = ++ idx ; stk [++ top] = u ; for ( register int i = head [u] ; i ; i = g [i].nxt ) { int v = g [i].to ; if ( ! dfn [v] ) { Dfs ( v ) ; if ( low [v] < low [u] ) low [u] = low [v] ; } else if ( ! place [v] && dfn [v] < low [u] ) low [u] = dfn [v] ; } if ( low [u] == dfn [u] ) { int tp = u, cur ; ++ scnt ; do { cur = stk [top --] ; place [cur] = scnt ; } while ( tp ^ cur ) ; } } int main ( ) { freopen ( "message.in", "r", stdin ) ; freopen ( "message.out", "w", stdout ) ; int n ; register int i, u, v, w, m ; for ( ; ; ) { n = read ( ), m = read ( ) ; if ( n == 0 && m == 0 ) return 0 ; if ( m == n - 1 ) { int ans ( 0 ) ; while ( m -- ) { u = read ( ), v = read ( ), w = read ( ) ; ans += w ; } printf ( "%d\n", ans ) ; continue ; } ecnt = 0 ; memset ( dfn, 0, sizeof ( int ) * n ) ; memset ( low, 0, sizeof ( int ) * n ) ; memset ( head, 0, sizeof ( int ) * n ) ; memset ( place, 0, sizeof ( int ) * n ) ; while ( m -- ) { u = read ( ), v = read ( ), w = read ( ) ; g [++ ecnt] = ( edge ) { v, head [u], w }, head [u] = ecnt ; } scnt = 0 ; idx = 0 ; Dfs ( 0 ) ; qcnt = 0 ; for ( u = 0 ; u < n ; ++ u ) for ( i = head [u] ; i ; i = g [i].nxt ) { v = g [i].to ; if ( place [u] ^ place [v] ) { e [++ qcnt] = ( Edge ) { place [u], place [v], g [i].w } ; } } printf ( "%d\n", Zhuliu_algorithm ( *place, scnt, qcnt, e ) ) ; } }
理论复杂度会T,还是踩标程,没办法(微笑)
相关文章推荐
- 朱刘算法模板(最小树形图)
- HDU 4009 Transfer water 最小树形图 朱刘算法
- POJ 3164 Command Network 朱刘算法求固定根最小树形图
- 最小树形图(朱刘算法)
- poj_3164 Command Network(最小树形图+朱刘算法)
- BZOJ 4349: 最小树形图(最小树形图->朱刘算法)
- 最小树形图/朱刘算法……表示稍微记录一下
- poj 3164 Command Network(最小树形图朱刘算法)
- POJ-3164 Command Network(最小树形图(有向图的最小生成树)[朱刘算法])
- poj 3164 最小树形图 初识朱刘算法
- poj 3164 Command Network(最小树形图—朱刘算法模版)
- 对朱刘算法求最小树形图的理解(uva11865)
- 图论--最小树形图朱刘算法模板
- POJ 3164 Command Network(最小树形图+朱刘算法)
- POJ3164 最小树形图 有向图的最小生成树 模板题 朱刘算法 朱永津-刘振宏算法
- HDU 2121 Ice_cream’s world II 无固定点的最小树形图 朱刘算法
- HDU 2121 Ice_cream's world II 朱刘算法求无固定根最小树形图
- HDU 4009 Transfer water 朱刘算法求无固定根最小树形图
- POJ--3164--Command Network【朱刘算法】最小树形图
- UVA-11183 Teen Girl Squad (最小树形图、朱刘算法模板)