URAL(timus)1709 Penguin-Avia(并查集)

Penguin-Avia

Time limit: 1.0 second
Memory limit: 64 MB

The Penguin-Avia airline, along with other Antarctic airlines, experiences financial difficulties because of the world‘s economic crisis. People of Antarctica economize on flights and use trains or prefer to stay at home. The airline‘s management hopes that the number of their clients will increase in the summer due to the tourists visiting the coastal resorts. In order to hold out till the summer, it was decided to optimize the flight scheme by cancelling some flights and introducing some new flights.

Director of Penguin-Avia assumes that after the optimization the flight scheme must have the following properties:

  1. Using one or more Penguin-Avia flights, one can get from any Antarctic airport to any other.
  2. The scheme must contain the minimal number of flights among all the schemes satisfying the first property.

However, not everything is that easy in Antarctica. For cancelling a flight, the airline must pay a one-time forfeit of d Antarctic dollars. To obtain slots for a new flight, the company must spend a Antarctic dollars to grease the palm of the godfather of the Antarctic mafia nicknamed Walrus.

Help Director of Penguin-Avia transform the existing flight scheme spending as little money as possible. For doing that, you will be presented with a travel card for all flights of the airline.

Input

In the first line you are given the number n of airports in Antarctica, 2 ≤ n ≤ 100. In the second line you are given the integers d and a, 1 ≤ d, a ≤ 106. The following n lines describe the existing scheme of Penguin-Avia flights in the form of an n × n matrix. There is “1” in a cell (i, j) of the matrix if the airline has flights between the airports i and j. Otherwise, there is “0” in the cell. It is guaranteed that the matrix is symmetric and there are only zeros on its diagonal.

Output

In the first line output the minimal amount of money necessary for the optimization of the existing flight scheme. In the next n lines give the plan of changing the scheme in the form of an n × n matrix. A cell (i, j) of this matrix contains the symbol “d” if the flights between the airports i and j should be cancelled. In the case when a new flight should be introduced between these airports, the cell contains the symbol “a”. The remaining cells contain the symbol “0”. The matrix must be symmetric. If there are several optimal schemes, output any one of them.

Sample

input output
6
2 3
011000
101000
110000
000011
000101
000110
7
0d0000
d00000
000a00
00a0d0
000d00
000000

Problem Author: Alexander Ipatov

【分析】给出一个图,双向的,现要你删除,添加一些边,使得所有点联通,删除,添加都需要费用,问你最小费用是多少。就是个简  单的并查集问题。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define inf 0x3f3f3f3f
#define mod 10000
typedef long long ll;
using namespace std;
const int N=105;
const int M=50000;
int power(int a,int b,int c){int ans=1;while(b){if(b%2==1){ans=(ans*a)%c;b--;}b/=2;a=a*a%c;}return ans;}
char w[N][N];
int vis[N][N],VIS[N][N];
int n,m,k,c;
ll s=0;
int parent[N];
int Find(int x)
{
    if(parent[x]!=x)parent[x]=Find(parent[x]);
    return parent[x];
}
void Union(int x,int y)
{
    x=Find(x);y=Find(y);
    if(x==y)return;
    parent[y]=x;
}
int main()
{
    for(int i=0;i<=100;i++)parent[i]=i;
    int a,d;
    scanf("%d%d%d",&n,&a,&d);
    for(int i=1;i<=n;i++){
        scanf("%s",w[i]+1);
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(w[i][j]==‘1‘){
                int x=Find(i);
                int y=Find(j);
                if(x==y)vis[i][j]=vis[j][i]=1,s+=a;
                else Union(i,j);
            }
        }
    }
    int ok=Find(1);
    for(int i=2;i<=n;i++){
        int x=Find(i);
        if(x!=ok&&vis[1][i]!=2)vis[1][i]=vis[i][1]=2,s+=d,Union(1,i);
    }
    printf("%lld\n",s);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            int x=Find(i);
            int y=Find(j);
            if(!vis[i][j])printf("0");
            else if(vis[i][j]==1)printf("d");
            else if(vis[i][j]==2)printf("a");
        }
        printf("\n");
    }
    return 0;
}

时间: 2024-11-03 02:49:39

URAL(timus)1709 Penguin-Avia(并查集)的相关文章

URAL 1982. Electrification Plan(并查集)

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1982 Some country has n cities. The government has decided to electrify all these cities. At first, power stations in k different cities were built. The other cities should be connected with the power

URAL - 1966 - Cycling Roads(并查集 + 判线段相交)

题意:n 个点,m 条边(1 ≤ m < n ≤ 200),问所有点是否连通(两条边相交,则该 4 点连通). 题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1966 -->>对于每条边,边上的两端点并入集合,枚举边与边,判断他们是否相交,是的话各点并入集合,最后看集合内元素的个数是否为n.. #include <cstdio> #include <cmath> const int MAXN = 200

URAL 1682 Crazy Professor (并查集)

[题目链接] http://acm.timus.ru/problem.aspx?space=1&num=1682 [题目大意] 给出k,从1开始不断地加一并把这个数写在黑板上,如果写上的数字和之前的数字满足 (a+b*b)%k=0或者(b+a*a)%k=0就在他们之间连一条线,如果黑板上出现环就结束,问能写几个数 [题解] 我们发现写到2k-1的时候,就一定会产生一个环,所以我们只要枚举数字 往满足要求的地方连边,判断是否出现环即可 [代码] #include <cstdio> #in

URAL 1671 Anansi&#39;s Cobweb (并查集)

题意:给一个无向图.每次查询破坏一条边,每次输出查询后连通图的个数. 思路:并查集.逆向思维,删边变成加边. #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<iostream> #define inf -100000000 #define LL long long #define maxn 100005 using namespace

Pilot Work Experience (URAL 1888 并查集+floyd)

Pilot Work Experience Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status Description Leonid had n Oceanic Airlines flights during his business trip. He studied the latest issue of the monthly on-board magazine o

种类并查集

//http://acm.timus.ru/problem.aspx?space=1&num=1003//分析:树和递归最常用的思想是分治:并查集是一种合并树的数据结构:合并树或加入树节点时,我们只在意新建立的树边上相邻的两个树节点之间的关系,实际上树边只在意相邻两个树节点之间的关系//思路:可以讲一段连续区间的奇偶性表示成两个前缀和的奇偶性:将出现的离散的点用map离散化一下:将数量减少的点做一次种类并查集 1 #include"iostream" 2 #include&qu

51nod 1204 Parity(并查集应用)

1204 Parity 题目来源: Ural 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 你的朋友写下一串包含1和0的串让你猜,你可以从中选择一个连续的子串(例如其中的第3到第5个数字)问他,该子串中包含了奇数个还是偶数个1,他会回答你的问题,然后你可以继续提问......你怀疑朋友的答案可能有错,或说同他之前的答案相互矛盾,例如:1 - 2 奇数,3 - 4 奇数,那么可以确定1 - 4 一定是偶数,如果你的朋友回答是奇数,就产生了矛盾.给出所有你朋友的

CodeForces 745C Hongcow Builds A Nation 并查集

题意: 给了你n个城市 m条边 k个政府 每个政府管辖的区域内不能和其他政府的区域有相连 即政府之间不存在路径 问你在维护这种关系的同时 最多再加多少条边 思路: 先找出来每个联通块 再找出来没有归属的孤立的点 把他们都放到最大的联通块里 然后每个联通块之间的点两两连边是n*(n-1)/2条边 最后算出来的ans-m就好了 (看别人的博客学了一个max_element 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a

并查集(个人模版)

并查集: 1 int find(int a) 2 { 3 int r=a; 4 while(f[r]!=r) 5 r=f[r]; 6 int i=a; 7 int j; 8 while(i!=r) 9 { 10 j=f[i]; 11 f[i]=r; 12 i=j; 13 } 14 return r; 15 } 16 int merge(int a,int b) 17 { 18 int A,B; 19 A=find(a); 20 B=find(b); 21 if(A!=B) 22 { 23 f[B