2019 Multi-University Training Contest 1

题号 A B C D E F G H I J K L M
状态 . . . Ο Ο . . . . . . . .

1004 Vacation

题意:给出n辆车距离终点的距离,车长,速度。当车撞上前面的车后,速度会和前面这辆车保持一致,求最后一辆车的车头经过终点所需要的时间。

思路:一个显然的结论,如果一辆车会撞上前面的车,那么最后经过终点的时间只和前面这辆车的速度有关,和本身的速度无关。所以我们用双指针,pos1代表当前车,pos2代表我要追赶的车,计算一下是否会在前面的车停下前碰到前面的车(我们假设最后一辆车的车头碰到终点时所有车辆瞬间停止),如果可以的话,那么pos1=pos2,pos2去找下一辆,如果不可以的话,pos2去找下一辆(当前的车不一定只会被前面的车影响)最终扫完找到的车就是最终状态的车速,简单计算可得答案。

#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
struct node{
    double len,dis,v;
}a[maxn];
int n;
double sum[maxn];
bool check(int pos1,int pos2){
    double t2=(a[pos2].dis+sum[pos2]-sum[1])/a[pos2].v;
    double t1=(a[pos1].dis+sum[pos1]-sum[1])/a[pos1].v;
    if(t1>t2)return false;
    return true;
}
int main(){
    while(cin>>n){
        n++;
        for(int i=1;i<=n;i++){
            scanf("%lf",&a[i].len);
            sum[i]=sum[i-1]+a[i].len;
        }
        for(int i=1;i<=n;i++){
            scanf("%lf",&a[i].dis);
        }
        for(int i=1;i<=n;i++){
            scanf("%lf",&a[i].v);
        }
        int pos1=1,pos2=2,car=1;
        while(pos2<=n){
            if(check(pos1,pos2)){
        //        printf("pos1:%d  pos2:%d\n",pos1,pos2);
                car=pos2;
                pos1=pos2,pos2++;
            }else{
                pos2++;
            }
        }
    //    printf("car:%d\n",car);
        printf("%.10f\n",(a[car].dis+sum[car]-sum[1])/a[car].v);
        
    }
}
View Code

1005  Path

题意:给出有向图,求阻塞若干条边,使得最短路变长或者阻塞,代价为阻塞的边长和,要求代价最小。

思路:先跑出所有的最短路,把属于最短路的边重新建图,原问题等价于求最小割。

这个想法很简单,但一万个点我不敢写,赛后想一下,感觉最短路的边可能很多,但一定不会是复杂度(即不会有很多拐弯的环),这样找网络流的增广路径的次数不会太多,所以不会超时(强行解释)

#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=10010;
ll inf=0x3f3f3f3f3f3f3f3f;
struct node {
    int u;
    ll w;
    friend bool operator<(const node &a,const node &b) {
        return a.w>b.w;
    }
};
priority_queue<node >q;
ll dis[2][maxn];
int n,m,u,v,tot[2],head[2][maxn];
ll w;
struct edge {
    int to,Next;
    ll w;
} a[2][maxn<<1];
struct ed{
    int u,v;
    ll w;
}in[maxn];
void init() {
    tot[0]=tot[1]=0;
    for(int i=1; i<=n; i++) {
        dis[0][i]=dis[1][i]=inf;
        head[0][i]=head[1][i]=-1;
    }
}
void addv(int u,int v,ll w,int typ) {
    a[typ][++tot[typ]].to=v;
    a[typ][tot[typ]].w=w;
    a[typ][tot[typ]].Next=head[typ][u];
    head[typ][u]=tot[typ];
}
void dij(int s,int t,int typ){
    dis[typ][s]=0;
    priority_queue<node >q;
    q.push({s,0});
    while(!q.empty()){
        node st=q.top();
        q.pop();
        int u=st.u;
        for(int i=head[typ][u];i!=-1;i=a[typ][i].Next){
            int v=a[typ][i].to;
            if(dis[typ][v]>dis[typ][u]+a[typ][i].w){
                dis[typ][v]=dis[typ][u]+a[typ][i].w;
                q.push({v,dis[typ][v]});
            }
        }
    }
}
struct Edge {
    int to;
    ll  flow;
    int  nxt;
    Edge() {}
    Edge(int to, int nxt, ll flow):to(to),nxt(nxt), flow(flow) {}
} edge[maxn << 2];

int hd[maxn], dep[maxn];
int S, T;
int N, tol;

void Init(int n) {
    N = n;
    for (int i = 0; i <=N; ++i) hd[i] = -1;
    tol = 0;
}

void add(int u, int v, ll w, ll rw = 0) {
    edge[tol] = Edge(v, hd[u], w);
    hd[u] = tol++;
    edge[tol] = Edge(u, hd[v], rw);
    hd[v] = tol++;
}

bool BFS() {
    for (int i = 0; i <= N; ++i) dep[i] = -1;
    queue<int>q;
    q.push(S);
    dep[S] = 1;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int i = hd[u]; ~i; i = edge[i].nxt) {
            if (edge[i].flow && dep[edge[i].to] == -1) {
                dep[edge[i].to] = dep[u] + 1;
                q.push(edge[i].to);
            }
        }
    }
    return dep[T] < 0 ? 0 : 1;
}

ll DFS(int u, ll f) {
    if (u == T || f == 0) return f;
    ll w, used = 0;
    for (int i = hd[u]; ~i; i = edge[i].nxt) {
        if (edge[i].flow && dep[edge[i].to] == dep[u] + 1) {
            w = DFS(edge[i].to, min(f - used, edge[i].flow));
            edge[i].flow -= w;
            edge[i ^ 1].flow += w;
            used += w;
            if (used == f) return f;
        }
    }
    if (!used) dep[u] = -1;
    return used;
}

ll Dicnic() {
    ll ans = 0;
    while (BFS()) {
        ans += DFS(S, inf);
    }
    return ans;
}

int main(){
    int TT;
    cin>>TT;
    while(TT--){
        cin>>n>>m;
        init();
        for(int i=1;i<=m;i++){
            scanf("%d%d%lld",&in[i].u,&in[i].v,&in[i].w);
            addv(in[i].u,in[i].v,in[i].w,0);
            addv(in[i].v,in[i].u,in[i].w,1);
        }
        dij(1,n,0);
        dij(n,1,1);
        tot[0]=0;
        for(int i=1; i<=n; i++) {
            head[0][i]=-1;
        }
        S=1,T=n;
        Init(n);
        for(int i=1;i<=m;i++){
            int u=in[i].u,v=in[i].v;
            ll w=in[i].w;
            if(dis[0][u]+w+dis[1][v]==dis[0][n]){
                add(u,v,w);
            }
        }
        printf("%lld\n",Dicnic());
    //    printf("debug\n");
    }
}
View Code

猜你喜欢

转载自www.cnblogs.com/mountaink/p/11231552.html