11.26补坑

#include <bits/stdc++.h>

using namespace std;
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
#define pb push_back
#define mem(a,k) memset(a,k,sizeof(a))
#define mp make_pair
typedef pair<int,int> P;
const int N = 1E5 + 7,inf = 0x3f3f3f3f;
struct node
{
    int to,val;
};
vector<node>g[N];
int d[N],n,m,ans[N],vis[N];
void bfs1()
{
    mem(d,-1);
    d[n] = 0;
    queue<P>que;
    que.push(mp(n,0));
    while(!que.empty()) {
        P u = que.front(); que.pop();
        for(int i = 0;i < g[u.first].size();i ++) {
            int to = g[u.first][i].to;
            if(d[to] == -1) {
                d[to] = d[u.first] + 1;
                que.push(mp(to,d[to]));
            }
        }
    }
    //for(int i = 1;i <= n;i ++) printf("%d ",d[i]);
}
void bfs2()
{
    mem(ans,0x3f);
    mem(vis,0);
    queue<int>que;
    que.push(1);
    vis[1] = 1;
    for(int i = 0;i < d[1];i ++) {
        vector<int>tmp;
        int res = inf;
        while(!que.empty()) {
            int u = que.front(); que.pop();
            tmp.push_back(u);
            for(int i = 0;i < g[u].size();i ++) {
                int to = g[u][i].to, val = g[u][i].val;
                if(d[to] == d[u]-1) {
                    res = min(res, val);
                }
            }
        }
        ans[i] = res;
        for(int& it:tmp) {
            for(auto& u:g[it]) {
                int to = u.to, val = u.val;
                if(d[to] == d[it]-1 && val == res && !vis[to]) {
                    que.push(to);
                    vis[to] = 1;
                }
            }
        }
    }
    printf("%d\n",d[1]);
    for(int i = 0;i < d[1];i ++) printf("%d%c",ans[i],i==d[1]-1?'\n':' ');
}
int main()
{
    while(scanf("%d%d",&n,&m) == 2) {
        rep(i,1,n) g[i].clear();
        rep(i,1,m) {
            int u, v, val;
            scanf("%d%d%d",&u,&v,&val);
            g[u].pb({v,val});
            g[v].pb({u,val});
        }
        bfs1();
        bfs2();
    }
    return 0;
}

UVA10129 题目链接:https://vjudge.net/contest/200148#problem/D

题意:输入n个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同,每个单词最多包含1000个小写字母,输入可以由重复。

题解:把字母看做节点,由于只是首位相连,每个单词只要首尾位即可,首位入度+1,末尾出度+1,合并。若有解,必须有欧拉路径。

先并查集看联通,然后判断度的关系即可。

#include <bits/stdc++.h>

using namespace std;
const int N = 30;
char s[1<<10];
int in[N], out[N], par[N], vis[N];
int find(int x){return x==par[x] ? x : par[x]=find(par[x]);}
void unit(int x, int y)
{
    x = find(x), y = find(y);
    if(x!=y) par[y] = x;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T --) {
        int n;
        for(int i = 0;i < 26;i ++) par[i] = i;
        memset(in, 0, sizeof(vis));
        memset(out,0,sizeof(out));
        scanf("%d",&n);
        for(int i = 1;i <= n;i ++) {
            scanf("%s",s);
            int len = strlen(s);
            in[s[0]-'a'] ++;
            out[s[len-1]-'a'] ++;
            unit(s[0]-'a', s[len-1]-'a');
        }
        int fg = 0;
        for(int i = 0;i < 26;i ++) {
            if((in[i]||out[i])&& i == par[i]) fg ++;
        }
        if(fg != 1) {
            puts("The door cannot be opened.");
        } else {
            int dif = 0;
            for(int i = 0;i < 26;i ++) {
                if(in[i] != out[i]) dif ++;
            }
            if(dif != 2 && dif != 0) {
                puts("The door cannot be opened.");
            } else {
                if(dif == 0) {
                    puts("Ordering is possible.");
                } else {
                    vector<int>vec;
                    for(int i = 0;i < 26;i ++) {
                        if(in[i] != out[i]) {
                            vec.push_back(i);
                        }
                    }
                    assert(vec.size() == 2);
                    bool flag = 0;
                    if(in[vec[0]] == 1 + out[vec[0]] && in[vec[1]] == -1 + out[vec[1]]) flag = 1;
                    swap(vec[0], vec[1]);
                    if(in[vec[0]] == 1 + out[vec[0]] && in[vec[1]] == -1 + out[vec[1]]) flag = 1;
                    if(flag) puts("Ordering is possible.");
                    else puts("The door cannot be opened.");
                }
            }
        }
    }
    return 0;
}
UVA1599

感觉这题很好紫书P1599,弱鸡只会2次BFS,感觉最妙的是第2次BFS,对每层BFS,取最优(好几个相同的话,都入队列)。

///

UVA11853

附上链接,看了这2个图和讲解终于知道怎么写了,难点在与从上放开始DFS,重点部分代码里标记了。


#include <bits/stdc++.h>

using namespace std;
const double R = 1000.0;
const int N = 1024;
int n;
pair<pair<int,int>,int>cir[N];
#define fi first
#define se second
double left_,right_;
bool vis[N];
inline bool ins(int a,int b)
{
    return hypot(fabs(cir[a].fi.fi-cir[b].fi.fi),fabs(cir[a].fi.se-cir[b].fi.se)) < cir[a].se + cir[b].se;
}
void update(int a)
{
    //附上链接里图片很好说明这2个更新
    if(cir[a].fi.fi - cir[a].se < 0) left_ = min(left_, cir[a].fi.se - sqrt(cir[a].se*cir[a].se-cir[a].fi.fi*cir[a].fi.fi)); .
    if(cir[a].fi.fi + cir[a].se > R) right_ = min(right_, cir[a].fi.se - sqrt(cir[a].se*cir[a].se-(R-cir[a].fi.fi)*(R-cir[a].fi.fi)));
}
bool dfs(int u)
{
    if(vis[u]) return false;
    vis[u] = 1;
    if(cir[u].fi.se < cir[u].se) return true; //某次这个圆与下方x轴接触了,则一定封闭了图形,无解
    for(int i = 0;i < n;i ++) {
        if(ins(u,i) && dfs(i)) return true;
    }
    update(u);
    return false;
}
int main()
{
    std::ios::sync_with_stdio(false), cin.tie(0);
    while(cin >> n) {
        memset(vis, 0, sizeof(vis));
        left_ = right_ = 1000;
        for(int i = 0;i < n;i ++) cin >> cir[i].fi.fi >> cir[i].fi.se >> cir[i].se;
        bool ok = true;
        for(int i = 0;i < n;i ++) {
            if(cir[i].fi.se+cir[i].se >= R && dfs(i)) { //说明与上方有接触,有可能形成封闭的图形,dfs才有意义。
                ok = false; break;
            }
        }
        if(ok) {
            cout << fixed << setprecision(2) << "0.00 " << left_ << " 1000.00 " << right_ << '\n';
        } else {
            cout << "IMPOSSIBLE\n";
        }
    }
    return 0;
}



/




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值