URAL 1003,1004

1003:

并查集在处理矛盾关系的应用,讲的比较好的题解

#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <vector>
#include <bitset>
#include <cstdio>
#include <string>
#include <numeric>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long  ll;
typedef unsigned long long ull;

int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};//up down left right
bool inmap(int x,int y,int n,int m){if(x<1||x>n||y<1||y>m)return false;return true;}
int hashmap(int x,int y,int m){return (x-1)*m+y;}

#define eps 1e-8
#define inf 0x7fffffff
#define debug puts("BUG")
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)
#define N 11111

map<int,int>mp;
struct node
{
    int l,r;
    char c;
}nd[N>>1];
int fa[N<<1];
int find(int x)
{
    if (fa[x]!=x)
        fa[x] = find(fa[x]);
    return fa[x];
}

int gao(int m,int cnt)
{
    for (int i = 0; i < m; ++i)
    {
        int l = mp[nd[i].l-1], r= mp[nd[i].r];
        char c = nd[i].c;
        int f1 = find(l), f2 = find(r), f3 = find(l+cnt), f4 = find(r+cnt);
        if (c == ‘e‘)
        {
            if (f1 == f4 && f2 == f3)
                return i;
            fa[f1] = f2;
            fa[f3] = f4;
        }
        else
        {
            if (f1 == f2)
                return i;
            fa[f1] = f4;
            fa[f2] = f3;
        }
    }
    return m;
}
int main()
{
    //read;
    int n,m;
    while (~scanf("%d",&n))
    {
        if (n == -1) break;
        scanf("%d",&m);
        mp.clear();
        int l, r, cnt = 0;
        char str[11];
        for (int i = 0; i < m; ++i)
        {
            scanf("%d%d%s",&l,&r,str);
            nd[i].l = l, nd[i].r = r;
            nd[i].c = str[0];
            if (mp.find(l-1) == mp.end())
                mp[l-1] = cnt++;
            if (mp.find(r) == mp.end())
                mp[r] = cnt++;
        }
        for (int i = 0; i < 2*cnt; ++i)
            fa[i] = i;
        int ans = gao(m,cnt);
        printf("%d\n", ans);
    }
    return 0;
}

 

1004:

能够加深对floyd理解的好题,当然还有另外的做法

#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <vector>
#include <bitset>
#include <cstdio>
#include <string>
#include <numeric>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long  ll;
typedef unsigned long long ull;

int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};//up down left right
bool inmap(int x,int y,int n,int m){if(x<1||x>n||y<1||y>m)return false;return true;}
int hashmap(int x,int y,int m){return (x-1)*m+y;}

#define eps 1e-8
#define inf 0x7ffffff
#define debug puts("BUG")
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)
#define N 155
int mp[N][N];
int dis[N][N];
int nxt[N][N];
stack<int>st;
int floyd(int n)
{
    int ans = inf;
    for (int k = 1; k <= n; ++k)
    {
        for (int i = 1; i < k; ++i)
            for (int j = i+1; j < k; ++j)
            {
                if (ans > dis[i][j] + mp[k][i] + mp[j][k])
                {
                    ans = dis[i][j] + mp[k][i] + mp[j][k];
                    while (!st.empty())
                        st.pop();
                    for (int t = i; t != j; t = nxt[t][j])
                        st.push(t);
                    st.push(j);
                    st.push(k);
                }
            }
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
            {
                if (dis[i][k] == inf || dis[k][j] == inf)
                    continue;
                if (dis[i][k] + dis[k][j] < dis[i][j])
                {
                    dis[i][j] = dis[i][k] + dis[k][j];
                    nxt[i][j] = nxt[i][k];
                }
            }
    }
    return ans;
}
int main()
{
    //read;
    int n,m;
    while (~scanf("%d",&n))
    {
        if (n == -1)break;
        scanf("%d",&m);
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
            {
                dis[i][j] = mp[i][j] = inf;
                nxt[i][j] = j;
            }
        int u,v,c;
        for (int i = 0; i < m; ++i)
        {
            scanf("%d%d%d",&u, &v, &c);
            if (mp[u][v] > c)
                mp[u][v] = mp[v][u] = dis[u][v] = dis[v][u] = c;
        }
        int ans = floyd(n);
        //printf("%d\n",ans);
        if (ans == inf)
            puts("No solution.");
        else
        {
            bool f = false;
            while (!st.empty())
            {
                if (f) printf(" ");
                else f = true;
                printf("%d",st.top());
                st.pop();
            }puts("");
        }
    }
    return 0;
}
时间: 2024-10-16 14:47:55

URAL 1003,1004的相关文章

SOJ 1002/1003/1004 大整数相加/相乘/相除

三个题目分别考察大整数相加相乘相除运算.如果按照传统算法是取一个长数组,之后进行模拟或者FFT来进行运算.但是相对繁琐. 后来昨天的青岛区域赛网赛1001,用到了JAVA的BigDecimal,于是反过来想到了这几个题目.用JAVA写了以后果然很简单. 1002:大数相加: AC代码: import java.util.*; import java.math.*; public class Main { public static void main(String[] args) { // TO

2016&quot;百度之星&quot; - 测试赛(热身,陈题)1001,1002,1003,1004

1001.大搬家 Accepts: 515 Submissions: 2005 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 近期B厂组织了一次大搬家,所有人都要按照指示换到指定的座位上.指示的内容是坐在位置ii上的人要搬到位置jj上.现在B厂有NN个人,一对一到NN个位置上.搬家之后也是一一对应的,改变的只有位次. 在第一次搬家后,度度熊由

补题清单

HDU 3585 HDU 1693 URAL 1519 FZU 1977 HDU 1964 HDU 3377 POJ 1739 POJ 3133 BZOJ 1025 HDU 4285 专题7 1003 1004 1005 1006 1008

ACM训练方案-POJ题目分类

ACM训练方案-POJ题目分类 博客分类: 算法 ACM online Judge 中国: 浙江大学(ZJU):http://acm.zju.edu.cn/ 北京大学(PKU):http://acm.pku.edu.cn/JudgeOnline/ 杭州电子科技大学(HDU):http://acm.hdu.edu.cn/ 中国科技大学(USTC):http://acm.ustc.edu.cn/ 北京航天航空大学(BUAA)http://acm.buaa.edu.cn/oj/index.php 南京

CSS实现的几款不错的菜单栏

前言 自从做了智慧城市这个项目之后,我一个做后端的开发者,瞬间转为前端开发,不过我还是很喜欢前端的.前端那些事,其实蛮有意思的,HTML实现的是静态的,使用ajax之后就可以和数据库交互了,加上js和jQuery之后就动起来了,加上CSS之后就更加炫酷了.因为项目中需要,查资料和编写了一些炫酷的二级菜单,分享给大家,好东西就要分享嘛! 一.滑动菜单 1.代码: 1 <!DOCTYPE HTML> 2 <html lang="en-US"> 3 <head&

requirejs--源码分析

1 /*---------------------------------------start-------------------------------*/ 2 req({}); // num == 1 跳到 num == 2 3 4 //Exports some context-sensitive methods on global require. 5 each([ 6 'toUrl', 7 'undef', 8 'defined', 9 'specified' 10 ], funct

2015苏州大学ACM-ICPC集训队选拔赛(3)题解

1001 1002 1003 1004 这是一道二进制题,题目上已经有提示了.n个树坑可以看成是n位二进制数,没有种树的位置上值为0,种树的位置上值为1.这样只需要枚举所有的n位二进制数,求出每一位上的值,再判断是否至少有1以及任意两个1之间是否距离至少为m. 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 6 using namespace st

plsql数组和嵌套

6 集合类型 6.1 数组 定义:由其元素的最大数目限定的单维有限集合,存放2GB(2*1024*1024*1024)个元素,排列是紧密的 (1)数组的定义.声明.初始化 A 数字类型的数组类型 declare  type num_varray is varray(5) of number;  v_numvarray num_varray:=num_varray(10,20,30,40);  --数组的声明+初始化begin  for idx in 1..4 loop    dbms_outpu

C语言写郑州大学校友通讯录

1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #define LEN sizeof(struct address_list) 5 6 /* 7 *************************通讯录结构体*********************************** 8 */ 9 10 struct address_list 11 { 12 char name[30]; /