zoj 3034 - The Bridges of Kolsberg

题目:在河两端有两排服务器,现在要把河两边相同的品牌型号的机器连起来,每个电脑有个值,

每个机器只能与另一台机器链接,并且不同的链接不交叉,现在要求链接的电脑总之最大。

分析:dp,最大公共子序列,字符串。还要加一个字符串处理。

说明:(2011-09-19 11:08)。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define max( a, b ) ((a)>(b)?(a):(b))

char LeftOS[ 1001 ][ 12 ];
char RightOS[ 1001 ][ 12 ];
int  LeftID[ 1001 ];
int  LeftV[ 1001 ];
int  RightID[ 1001 ];
int  RightV[ 1001 ];
char OSList[ 1001 ][ 12 ];
int  Match[ 1001 ][ 1001 ];
int  Count[ 1001 ][ 1001 ];
int  Number = 0;

int ID( char * Data )
{
    for ( int i = 0 ; i < Number ; ++ i )
        if ( !strcmp( OSList[ i ], Data ) )
            return i;
    strcpy( OSList[ Number ], Data );
    return Number ++;
}

int main()
{
    int  t,n,m;
    char City[ 12 ];
    while ( ~scanf("%d",&t) )
    while ( t -- ) {
        scanf("%d",&n);
        for ( int i = 1 ; i <= n ; ++ i )
            scanf("%s %s %d",City,LeftOS[ i ],&LeftV[ i ]);
        scanf("%d",&m);
        for ( int i = 1 ; i <= m ; ++ i )
            scanf("%s %s %d",City,RightOS[ i ],&RightV[ i ]);

        Number = 0;
        for ( int i = 1 ; i <= n ; ++ i )
            LeftID[ i ] = ID( LeftOS[ i ] );
        for ( int i = 1 ; i <= m ; ++ i )
            RightID[ i ] = ID( RightOS[ i ] );

        memset( Match, 0, sizeof( Match ) );
        memset( Count, 0, sizeof( Count ) );

        for ( int i = 1 ; i <= n ; ++ i )
        for ( int j = 1 ; j <= m ; ++ j ) {
            if ( Match[ i ][ j ] < Match[ i-1 ][ j ] ) {
                Match[ i ][ j ] = Match[ i-1 ][ j ];
                Count[ i ][ j ] = Count[ i-1 ][ j ];
            }
            if ( Match[ i ][ j ] < Match[ i ][ j-1 ] ) {
                Match[ i ][ j ] = Match[ i ][ j-1 ];
                Count[ i ][ j ] = Count[ i ][ j-1 ];
            }
            if ( LeftID[ i ] == RightID[ j ] && Match[ i ][ j ] < Match[ i-1 ][ j-1 ] + LeftV[ i ] + RightV[ j ] ) {
                Match[ i ][ j ] = Match[ i-1 ][ j-1 ] + LeftV[ i ] + RightV[ j ];
                Count[ i ][ j ] = Count[ i-1 ][ j-1 ] + 1;
            }
        }

        printf("%d %d\n",Match[ n ][ m ],Count[ n ][ m ]);
    }
    return 0;
}
时间: 2024-08-02 15:18:30

zoj 3034 - The Bridges of Kolsberg的相关文章

ZOJ 2588 Burning Bridges(无向图求割边)

ZOJ 2588 Burning Bridges 链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 题意:给定一个无向图连通图,(其中可能有重边),要求去掉一条边之后,使得整个图不再连通.输出这些符合条件的边的序号. 思路:这就是一个简单的无向图求割边,需要注意的是这个无向图有重边,重边一定不是割边. 代码: /*========================================= 无向图求割点

ZOJ 1588 Burning Bridges (tarjan求割边)

题目链接 题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M). 思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] < low[v],则边(u,v)是割边. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace st

2014 Super Training #2 F The Bridges of Kolsberg --DP

原题:UVA 1172  http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3613 动态规划问题. 定义: dp[i] = 右岸前i个村庄(m岸)能够与左岸(n岸)不交叉匹配的最大权值和最小桥数 (用pair<int,int> 维护两个值) 方程: dp[i].first = max(dp[i].first,dp[i-1].fir

ZOJ 2588 Burning Bridges 求无向图桥 边双连通裸题

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 binshen的板子: #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #i

zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】

Burning Bridges Time Limit: 5 Seconds      Memory Limit: 32768 KB Ferry Kingdom is a nice little country located on N islands that are connected by M bridges. All bridges are very beautiful and are loved by everyone in the kingdom. Of course, the sys

ZOJ 2588 Burning Bridges(强连通分量)

题目地址:ZOJ 2588 因为数组开小了而TLE了..这题就是一个求无向连通图最小割边.只要判断dfn[u]是否<low[v],因为low指的当前所能回到的祖先的最小标号,加入low[v]大于dfn[u]时,说明v无法通过其他边回到u之前的点,也就是说v如果想要回到u的祖先点,必须要经过u点,那这条边很明显就是一条割边.这题还要去重边,假如有重边的话,说明怎么销毁哪条边总能通过另一条边,所以只要有重边,说明这两点之间没有割边. 代码如下: #include <iostream> #in

【求无向图的桥,有重边】ZOJ - 2588 Burning Bridges

模板题——求割点与桥 题意,要使一个无向图不连通,输出必定要删掉的边的数量及其编号.求桥的裸题,可拿来练手. 套模板的时候注意本题两节点之间可能有多条边,而模板是不判重边的,所以直接套模板的话,会将重边也当做桥输出,因此要在判断桥的时候加一个判断,即当且仅当两点之间仅有一条边,且满足dfn[cur] < low[i],(cur, i)才是桥. 另外本题节点数为105,用邻接矩阵的话会内存超限,所以我用了了一个multiset存储边及其编号. 代码如下: 1 #include<cstdio>

ZOJ 2588 Burning Bridges(无向连通图求割边)

题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大于dfn[u]时,说明v无法通过其它边回到u之前的点.也就是说v假设想要回到u的祖先点.必需要经过u点,那这条边非常明显就是一条割边.这题还要去重边,假如有重边的话.说明怎么销毁哪条边总能通过还有一条边,所以仅仅要有重边.说明这两点之间没有割边. 代码例如以下: #include <iostream&g

ZOJ 2588 Burning Bridges(判断割边)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 题意: Ferry王国是一个漂亮的岛国,一共有N个岛国.M座桥,通过这些桥可以从每个小岛都能 到达任何一个小岛.很不幸的是,最近Ferry王国被Jordan征服了.Jordan决定烧毁所有的桥. 这是个残酷的决定,但是Jordan的谋士建议他不要这样做,因为如果烧毁所有的桥梁,他自己的 军队也不能从一个岛到达另一个岛.因此Jordan决定烧尽可能多的桥,只