92 条题解
-
1zwz LV 7 @ 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; }
清爽(丑陋)的代码
-
12019-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; }
-
12017-06-06 19:42:17@
1开始j打成i了,郁闷
-
12017-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()); } }
-
02017-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; }
-
02016-11-12 13:40:39@
第一次---10分--难过
于是来翻了翻题解,看着吐槽,我笑着笑着就忘了我的代码哪错了——于是我又把那份代码提交了(哦不)
最后,再次翻阅题解,
改掉了:
x,y,t是实数型,要用float -
02015-10-19 19:51:35@
怕精度问题就不要开方啊。。。雪崩
-
02015-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;
}
读入。。。 -
02015-04-05 10:18:23@
读入一定要用“read”,血的教训。
-
02014-07-07 13:25:47@
把j打成i还查了好几次,晕==||
-
02012-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,数据规模是' -
02010-03-13 15:20:10@
Accepted 有效得分:100 有效耗时:0ms
典型的匈牙利算法~~
-
02009-11-07 16:23:16@
是不是题目没说清楚啊,输入问题!
readln-->real wa 了n次 -
02009-11-07 10:30:52@
...匈牙利的判重位置写错了。。。囧rz。
-
02009-11-06 22:10:25@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0ms
距离比较时,将>=打成了>,结果85,害我wa了一次 -
02009-11-04 19:08:38@
编译通过...
├ 测试数据 01:答案正确... 338ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:338msprogram 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)) -
02009-11-03 12:54:33@
readln -> 10 分
read -> AC -
02009-10-26 20:09:20@
题目骗我说多组数据啊。。
写了个while not eof do。
卡了两台评测机。
后来6k评超时。再交碰上Smdcn就AC了- - -
02009-10-25 12:25:32@
赤裸裸的二分图最大匹配。。。但是本菜不会……
-
02009-10-24 16:44:25@
85分AC...