题解

92 条题解

  • 1
    @ 2022-03-22 08:28:18
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1005; 
    struct xb{
        double x,y,v;
    }q[N];
    struct poi{
        double x,y;
    }p[N];
    int n,m,t;
    vector<int>e[N];
    int vis[N];
    int mch[N];
    bool dfs(int u,int tag) {
        if(vis[u]==tag) return 0;
        vis[u]=tag;
        for (int i=0;i<e[u].size();i++){
            int v=e[u][i];
            if(!mch[v]||dfs(mch[v],tag)){
                mch[v]=u;
                return 1;
            }   
        }
        return 0;
    }
    int main(){
        cin>>m>>n>>t;
        int i,j,ans=0;
        for(i=1;i<=n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        for(i=1;i<=m;i++)
            scanf("%lf%lf%lf",&q[i].x,&q[i].y,&q[i].v);
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                if(pow(p[i].x-q[j].x,2)+pow(p[i].y-q[j].y,2)<=pow(q[j].v*t,2))
                    e[i].push_back(j);
        for(i=1;i<=n;i++)
            if(dfs(i,i))
                ans++;
        printf("%d",ans);
        return 0;
    }
    

    清爽(丑陋)的代码

  • 1
    @ 2019-09-14 16:21:34

    匈牙利算法,题目输入注意(因为顺序不对错交n次QAQ),第一行m,n,t,之后是n行,再m行。

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    typedef struct
    {
        double x,y,v;
    }pp;
    
    typedef struct
    {
        double x,y;
    }hole;
    
    int n,m,t;
    pp pps[1001];
    hole hos[1001];
    bool ma[1001][1001]={0};
    bool vis[1001]={0};
    int fa[1001]={0};
    
    bool found(int x)
    {
        int i;
        for(i=1;i<=m;i++)
        {
            if(ma[x][i]&&!vis[i])
            {
                vis[i]=true;
                if(fa[i]==0||found(fa[i]))
                {
                    fa[i]=x;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main()
    {
        cin>>m>>n>>t;
        int i,j,ans=0;
        for(i=1;i<=n;i++)
        {
            cin>>hos[i].x>>hos[i].y;
        }
        for(i=1;i<=m;i++)
        {
            cin>>pps[i].x>>pps[i].y>>pps[i].v;
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if((hos[i].x-pps[j].x)*(hos[i].x-pps[j].x)+(hos[i].y-pps[j].y)*(hos[i].y-pps[j].y)<=(pps[j].v*t)*(pps[j].v*t))
                {
                    ma[i][j]=true;
                }
            }
        }
        for(i=1;i<=n;i++)
        {
            memset(vis,0,sizeof(vis));
            if(found(i))
            {
                ans++;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 1
    @ 2017-06-06 19:42:17

    1开始j打成i了,郁闷

  • 1
    @ 2017-06-06 19:39:52
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    int n,m;
    vector<int> l;
    vector<vector<int> > a_b_r;
    double t;
    vector<double> a_x;
    vector<double> a_y;
    vector<double> a_v;
    vector<double> b_x;
    vector<double> b_y;
    vector<bool> c;
    
    void c_v_1()
    {
        l.resize(0);
        a_b_r.resize(0);
        a_x.resize(0);
        a_y.resize(0);
        a_v.resize(0);
        b_x.resize(0);
        b_y.resize(0);
    }
    
    int find_1(int now)
    {
        for (int i=1;i<a_b_r[now].size();i++)
            if (c[a_b_r[now][i]]==0)
            {
                int temp=l[a_b_r[now][i]];
                l[a_b_r[now][i]]=now,c[a_b_r[now][i]]=1;
                if (temp>0)
                {
                    if (find_1(temp)==1)
                        return 1;
                }
                else
                    return 1;
                l[a_b_r[now][i]]=temp;
            }
        return 0;
    }
    
    int work_1()
    {
        int ans=0;
        for (int i=1;i<=n;i++)
        {
            c.resize(0);
            c.resize(m+1,0);
            ans+=find_1(i);
        }
        return ans;
    }
    
    int main()
    {
        while (~scanf("%d%d%lf",&n,&m,&t))
        {
            c_v_1();
            b_x.resize(m+1,0);
            b_y.resize(m+1,0);
            for (int i=1;i<=m;i++)
                scanf("%lf%lf",&b_x[i],&b_y[i]);
            a_x.resize(n+1,0);
            a_y.resize(n+1,0);
            a_v.resize(n+1,0);
            for (int i=1;i<=n;i++)
                scanf("%lf%lf%lf",&a_x[i],&a_y[i],&a_v[i]);
            a_b_r.resize(n+1);
            for (int i=1;i<=n;i++)
            {
                a_b_r[i].resize(1,0);
                for (int j=1;j<=m;j++)
                    if (pow(pow(fabs(a_x[i]-b_x[j]),double(2))+pow(fabs(a_y[i]-b_y[j]),double(2)),double(1)/2)<=a_v[i]*t)
                        a_b_r[i].push_back(j);
            }
            l.resize(m+1,0);
            printf("%d\n",work_1());
        }
    }
    
  • 0
    @ 2017-02-15 13:34:31

    测试数据 #0: Accepted, time = 78 ms, mem = 3028 KiB, score = 15
    测试数据 #1: Accepted, time = 62 ms, mem = 1480 KiB, score = 15
    测试数据 #2: Accepted, time = 31 ms, mem = 1096 KiB, score = 15
    测试数据 #3: Accepted, time = 0 ms, mem = 940 KiB, score = 10
    测试数据 #4: Accepted, time = 15 ms, mem = 1092 KiB, score = 15
    测试数据 #5: Accepted, time = 15 ms, mem = 1088 KiB, score = 15
    测试数据 #6: Accepted, time = 31 ms, mem = 1092 KiB, score = 15
    Accepted, time = 232 ms, mem = 3028 KiB, score = 100

    最开始两次莫名其妙的越界。。明明是1010都不行吗 变成10010就AC了。。
    裸的二分图匹配 这里用网络流解了

    #include<iostream>
    #include<iomanip>
    #include<cstring>
    #include<vector>
    #include<sstream>
    #include<algorithm>
    #include<string>
    #include<cstdio>
    #include<math.h>
    #include<map>
    #include<cctype>
    #include<queue>
    #include<functional>
    #include<set>
    #define lson l , m , rt << 1  
    #define rson m + 1 , r , rt << 1 | 1  
    #define Mem(a,b) memset((a),(b),sizeof((a)))
    #define Sy system("pause")
    const int maxn = 10000 + 10;
    const int INF = 1e9;
    using namespace std;
    typedef long long LL;
    struct Dinic{
        struct Edge {
            int from, to, cap, flow;
            Edge(int a, int b, int c, int d) :from(a), to(b), cap(c), flow(d) {}
            Edge(){}
            friend bool operator < (const Edge& a, const Edge& b) {
                return a.from < b.from || (a.from == b.from && a.to < b.to);
            }
        };
    
        int n, m, s, t;
        vector<Edge> old;
        vector<Edge> edges;//边数两倍
        vector<int> G[maxn];
        bool vis[maxn]; // BFS使用
        int d[maxn];
        int cur[maxn];
    
        void init(int n){ this->n = n; for (int i = 0; i < n; i += 1)G[i].clear(); edges.clear(); }
    
        void AddEdge(int from, int to, int cap){
            edges.push_back(Edge(from, to, cap, 0));
            edges.push_back(Edge(to, from, 0, 0));
            m = edges.size();
            G[from].push_back(m - 2);
            G[to].push_back(m - 1);
        }
    
        bool BFS(){  //构建层次网络,如果构建的时候汇点没有访问过证明已经不在网络中
            Mem(vis, 0);
            queue<int> Q;
            Q.push(s);
            vis[s] = 1;
            d[s] = 0;
            while (!Q.empty()){
                int x = Q.front(); Q.pop();
                for (int i = 0; i<G[x].size(); i += 1){
                    Edge & e = edges[G[x][i]];
                    if (!vis[e.to] && e.cap > e.flow){
                        vis[e.to] = 1;
                        d[e.to] = d[x] + 1;//层次
                        Q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
    
        int DFS(int x, int a){
            if (x == t || a == 0) return a;//如果已经到汇点或者增量是0,没必要继续因为已经找到了最大流
            int flow = 0, f;
            for (int & i = cur[x]; i<G[x].size(); i += 1){
                Edge& e = edges[G[x][i]];
                //如果e.to是x的儿子结点并且其增量大于0
                if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0){
                    e.flow += f;
                    edges[G[x][i] ^ 1].flow -= f;
                    flow += f;
                    a -= f;
                    if (!a) break;
                }
            }
            return flow;
        }
    
        int MaxFlow(int s, int t){
            this->s = s; this->t = t;
            int flow = 0;
            while (BFS()){
                Mem(cur, 0);
                flow += DFS(s, INF);
            }
            return flow;
        }
    };
    
    //小杉家族r个人正在一片空地上散步,突然,外星人来了……
    //留给小杉家族脱逃的时间只有t秒,每个小杉都有一个跑的速度v
    //总共有a个传送点,小杉们必须在t秒内到达传送点才能脱逃
    //每组测试数据的
    //第一行有三个整数r和a和t(0<a, r, t <= 1000)
    //第二行有a对实数,第i对数表示第i个传送点的坐标,这些坐标绝对值均不超过1e6
    //接下来r行,每行有三个实数x, y, v,表示第i个小杉的坐标和奔跑的速度
    // S:0 人:[1,r] 传送门:[r+1,r+a] T:r+a+1;
    struct node
    {
        float x, y, v;
        node(){}
        node(float a, float b, float c = 0.0) :x(a), y(b), v(c) {}
    };
    int r, a, t;
    bool canrch(const node & a, const node & b){
        return (
            sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) <= (a.v * t)
            );
    }
    int main(){
        Dinic D;
        scanf("%d %d %d", &r, &a, &t);
        D.init(r + a + 2);
        float x, y, v;
        int s = 0, t = r + a + 1;
        vector<node> people, gate;
        for (int i = r + 1; i <= r + a; i += 1){
            scanf("%f %f", &x, &y);
            gate.push_back(node(x, y));
            D.AddEdge(i, t, 1);
        }
        for (int i = 1; i <= r; i += 1){
            scanf("%f %f %f", &x, &y, &v);
            people.push_back(node(x, y, v));
            D.AddEdge(s, i, 1);
        }
        for (int i = 1; i <= r; i += 1){
            node & p = people[i - 1];
            for (int j = 1; j <= a; j += 1){
                node & g = gate[j - 1];
                if (canrch(p, g))
                    D.AddEdge(i, j + r, 1);
            }
        }
        printf("%d\n", D.MaxFlow(s, t));
        Sy;
        return 0;
    }
    
  • 0
    @ 2016-11-12 13:40:39

    第一次---10分--难过
    于是来翻了翻题解,看着吐槽,我笑着笑着就忘了我的代码哪错了——于是我又把那份代码提交了(哦不)
    最后,再次翻阅题解,
    改掉了:
    x,y,t是实数型,要用float

  • 0
    @ 2015-10-19 19:51:35

    怕精度问题就不要开方啊。。。雪崩

  • 0
    @ 2015-07-08 22:03:29

    P1212Way Selection
    Accepted

    记录信息

    评测状态 Accepted
    题目 P1212 Way Selection
    递交时间 2015-07-08 22:02:36
    代码语言 C++
    评测机 VijosEx
    消耗时间 91 ms
    消耗内存 4236 KiB
    评测时间 2015-07-08 22:02:43

    评测结果

    编译成功

    测试数据 #0: Accepted, time = 46 ms, mem = 4236 KiB, score = 15

    测试数据 #1: Accepted, time = 15 ms, mem = 4236 KiB, score = 15

    测试数据 #2: Accepted, time = 15 ms, mem = 4236 KiB, score = 15

    测试数据 #3: Accepted, time = 0 ms, mem = 4236 KiB, score = 10

    测试数据 #4: Accepted, time = 0 ms, mem = 4232 KiB, score = 15

    测试数据 #5: Accepted, time = 0 ms, mem = 4232 KiB, score = 15

    测试数据 #6: Accepted, time = 15 ms, mem = 4232 KiB, score = 15

    Accepted, time = 91 ms, mem = 4236 KiB, score = 100

    代码

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>

    using namespace std;

    int r , a , t;
    float x[1000 + 2];
    float y[1000 + 2];
    float x1d[1000 + 2];
    float y1d[1000 + 2];
    float v[1000 + 2];
    int use[1000 + 2];
    int graph[1000 + 2][1000 + 2];
    int match[1000 + 2];
    int ans;
    int i , j;

    bool hungary( int x )
    {
    int i;
    for( i = 1 ; i <= a ; i++ )
    if( graph[x][i] && !use[i] )
    {
    use[i] = 1;
    if( !match[i] || hungary( match[i] ) )
    {
    match[i] = x;
    return 1;
    }
    }
    return 0;
    }

    int main()
    {
    scanf( "%d %d %d" , &r , &a , &t );
    for( i = 1 ; i <= a ; i++ )
    scanf( "%f %f" , &x[i] , &y[i] );
    for( i = 1 ; i <= r ; i++ )
    scanf( "%f %f %f" , &x1d[i] , &y1d[i] , &v[i] );
    for( i = 1 ; i <= a ; i++ )
    for( j = 1 ; j <= r ; j++ )
    if( sqrt( ( x1d[j] - x[i] ) * ( x1d[j] - x[i] ) + ( y1d[j] - y[i] ) * ( y1d[j] - y[i] ) ) - v[j] * t <= 0 )
    graph[j][i] = 1;
    for( i = 1 ; i <= r ; i++ )
    {
    memset( use , 0 , sizeof( use ) );
    if( hungary( i ) )
    ans++;
    }
    cout << ans << endl;
    return 0;
    }
    读入。。。

  • 0
    @ 2015-04-05 10:18:23

    读入一定要用“read”,血的教训。

  • 0
    @ 2014-07-07 13:25:47

    把j打成i还查了好几次,晕==||

  • 0
    @ 2012-10-06 15:41:19

    每次看题解到一半就会无奈地放弃……太长了。总结一下,看看你有没有出现以下错误,没有的话,往下看大牛们的吧。

    [首先说明,此题正解是二分图的最大匹配,使用匈牙利算法或者网络流]

    1、i,j写反[请不要笑,下面有位神牛笑了别人结果rp--自己也写反了]

    2、精度问题,据说判断要用速度*时间>=距离判断[往下找你可以看到红字部分]

    3、知道为什么有精度问题吗?因为数据中t和坐标是实数,real和double都可以

    4、读入问题……用read不要用readln。不然WA10,看题目"第二行有a对实数,第i对数表示第i个传送点的坐标,这些坐标绝对值均不超过1e6"

    5、还是读入问题,写数据规模的人很不厚道,读入是r,a,t,数据规模是'

  • 0
    @ 2010-03-13 15:20:10

    Accepted 有效得分:100 有效耗时:0ms

    典型的匈牙利算法~~

  • 0
    @ 2009-11-07 16:23:16

    是不是题目没说清楚啊,输入问题!

    readln-->real wa 了n次

  • 0
    @ 2009-11-07 10:30:52

    ...匈牙利的判重位置写错了。。。囧rz。

  • 0
    @ 2009-11-06 22:10:25

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    距离比较时,将>=打成了>,结果85,害我wa了一次

  • 0
    @ 2009-11-04 19:08:38

    编译通过...

    ├ 测试数据 01:答案正确... 338ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:338ms

    program p1212;

    var a:array[1..1000,1..1000] of boolean;

    x,y:array[1..1000] of real;

    link:array[1..1000] of integer;

    v:array[1..1000] of boolean;

    i,j,k,l,m,n,ans,p,q,r:integer;

    c,d,w:real;

    function find(x:integer):boolean;

    var g:integer;

    begin

    for g:=1 to m do

    if a[x,g] and not v[g]

    then begin v[g]:=true;

    if (link[g]=0) or (find(link[g]))

    then begin link[g]:=x;exit(true);end;

    end;

    exit(false);

    end;

    begin

    read(m,n,k);

    for i:=1 to n do read(x[i],y[i]);

    for i:=1 to m do begin

    read(c,d,w);

    for j:=1 to n do

    begin

    if sqrt(sqr(x[j]-c)+sqr(y[j]-d))

  • 0
    @ 2009-11-03 12:54:33

    readln -> 10 分

    read -> AC

  • 0
    @ 2009-10-26 20:09:20

    题目骗我说多组数据啊。。

    写了个while not eof do。

    卡了两台评测机。

    后来6k评超时。再交碰上Smdcn就AC了- -

  • 0
    @ 2009-10-25 12:25:32

    赤裸裸的二分图最大匹配。。。但是本菜不会……

  • 0
    @ 2009-10-24 16:44:25

    85分AC...

信息

ID
1212
难度
7
分类
图结构 | 二分图 点击显示
标签
(无)
递交数
2251
已通过
501
通过率
22%
被复制
4
上传者