===20180717SHU暑期集训组队赛(5)===

又tm垫底了

两道图论+二分答案没过

模板 迪杰斯特拉最短路 + 二分答案

     二分图匹配+二分答案

特点:最大化其中最小值(最小化其中最大值)

多源bfs?最小化最远距离(对于状态而言) https://vjudge.net/contest/237325#problem/D()

先打两个模板压压惊,去洛谷啊

E dij+二分

#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const LL INF = LL(1)<<50;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int N=10010;
const int M=500010;
struct node
{
    int x;
    LL val;
    bool operator < (const node&a)const
    {
        return val>a.val;
    }
};
vector<node> G[N];
int vis[N];
LL dis[N];
int n,m,x;
int mz;
bool Dij(LL lim)
{
    clr(vis,0);
    for(int i=0;i<=n;i++) dis[i]=INF;
    priority_queue<node> q;
    dis[1]=0;
    q.push(node{1,0});
    node tmp;
    while(!q.empty())
    {
        tmp=q.top();
        q.pop();
        int u=tmp.x;
        if(vis[u]) continue;
        vis[u]=1;
        for(auto nd:G[u])
        {
            int v=nd.x;
            LL cost=nd.val;
            if(cost > lim) continue;
            if(!vis[v]&&dis[v]>dis[u]+cost)
            {
                dis[v]=dis[u]+cost;
                q.push(node{v,dis[v]});
            }
        }
    }
    if(dis[n]<=mz) return true;
    return false;
}
void showg(){
    for(int i=1;i<=n;i++){
        for(auto v:G[i])
            cout<<v.x<<" "<<v.val;
            cout<<endl;
    }
}

int main()
{
    fastin
    cin>>n>>m>>x;
    for(int i=0,u,v;i<m;i++){
        LL dis;
        cin>>u>>v>>dis;
        G[u].push_back (node{v,dis});
        G[v].push_back (node{u,dis});
    }
    Dij(1e7);
    mz=dis[n]*(1.0+x/100.0);
    LL l=0,r=INF;
    while(r-l>1){
        LL mid=l+(r-l)/2;
        if( Dij(mid) ) r=mid;
        else l=mid;
    }
    cout<<r<<endl;

    return 0;
}

 

J 二分图匹配+二分

#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int N=5010;
const int M=50010;
vector<int> G[N];
int link[N],used[N];
int n,m;
int uN;
bool dfs(int u)
{
    for(auto v:G[u])
    {
        if(!used[v])
        {
            used[v]=1;
            if(link[v]==-1||dfs(link[v]))
            {
                link[v]=u;
                return true;
            }
        }
    }
    return false;
}
int hungary()
{
    int res=0;
    memset(link,-1,sizeof link);
    for(int u=1; u<=uN; u++)
    {
        clr(used,0);
        if(dfs(u)) res++;
    }
    return res;
}
int dis[110][110];

bool judge(int lim)
{
    for(int i=0; i<=n; i++) G[i].clear();

    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            if(dis[i][j]<=lim) {
                G[i].pb(j+n);
                G[j+n].pb(i);
            }
    return hungary()==n;
}

int xx[240];
int yy[240];
int main()
{
    fastin
    cin>>n;
    uN=n;
    for(int i=1; i<=2*n; i++)
    {
        cin>>xx[i]>>yy[i];
    }
    for(int i=1; i<=n; i++)
        for(int j=n+1; j<=2*n; j++)
            dis[i][j-n] = abs(xx[i]-xx[j])+abs(yy[i]-yy[j]);


    int l=0,r=1e8;
    while(r-l>1)
    {
        int mid=l+(r-l)/2;
        if(judge(mid)) r=mid;
        else l=mid;
        //cout<<mid<<endl;
    }

    cout<<r<<endl;


    return 0;
}

 

二分答案题感觉都是

00000000000001111111111111111111(求第一个1)

11111111111111110000000000000000(求第一个0)

而不能解决  类似于

0111111000011111000011111000000(求第一个0)

记住就好了

G

大意:有多个点,对于每个点,给定它的坐标和曼哈顿半径,求有几个交点

0个就impossible 1就输出那个交点 2就uncertain

最多 4e6*1+1e6 * 1000

好气啊 当时都想出来了 复杂度推错了

#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
struct node{
    int x,y;
    bool operator< (const node&a)const
    {
        return x<a.x;
    }
};
vector<node> st[2];
int main(){
    fastin
    int n;cin>>n;
    int x,y,dis;cin>>x>>y>>dis;
    for(int i=-dis;i<=dis;i++){
        st[0].push_back(node{x+i,y+dis-abs(i)});
        if(i!=-dis && i!= dis)
        st[0].push_back(node{x+i,y-dis+abs(i)});
    }
    int flag=1;
    for(int i=1;i<n;i++){
        st[flag].clear();
        cin>>x>>y>>dis;
        for(auto v:st[1^flag])
            if(abs(x-v.x)+abs(y-v.y)==dis)
            st[flag].push_back(node{v.x,v.y});
        flag^=1;
    }
    flag^=1;
    /*
    for(int i=0;i<2;i++){
        for(auto v:st[i])
            cout<<v.x<<" "<<v.y<<endl;
        cout<<endl;
    }
    */
    if(st[flag].size()==1)  cout<<st[flag][0].x<<" "<<st[flag][0].y<<endl;
    else if(st[flag].size()==0) puts("impossible");
    else puts("uncertain");
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值