UVALive 7525

来源:互联网 发布:电脑写小说的软件 编辑:程序博客网 时间:2024/06/16 09:25

题目:传送门

思路:主要就是难在模型转换,只要看破,这道题就是很简单的最短路。s点t点以及每束光线的源点建立边,边的权值就是穿过这条边的光束数量。之后就是spfa跑一下s到t的最短路。在判断线段和射线相交的时候卡了很久。。。之前用一般式,连案例都跑不出,后来才想到斜率不存在的时候没有判断╮(╯▽╰)╭,然后直接换了参数方程写就不用判断斜率了。

下面是代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<algorithm>#define N 210#define INF 0x3f3f3f3f#define LL long long#define EPS 1e-8using namespace std;struct point{    double x,y;    point(){};    point(double x,double y){        this->x=x;        this->y=y;    }};struct line{    point s,t;    line(){};    line(point s,point t){        this->s=s;        this->t=t;    }}l[205];int n;point s,t;int g[N][N];int dist[N];  bool visit[N];  double kross(point a,point b){    return a.x*b.y-a.y*b.x;}bool pd(line a,line b){    /*if(a.s.x==b.s.x&&a.s.y==b.s.y||a.t.x==b.s.x&&a.t.y==b.s.y)        return false;*/    point d1=point(a.t.x-a.s.x,a.t.y-a.s.y);    //cout<<d1.x<<' '<<d1.y<<endl;    point d2=point(b.t.x-b.s.x,b.t.y-b.s.y);    //cout<<d2.x<<' '<<d2.y<<endl;    point d3=point(a.s.x-b.s.x,a.s.y-b.s.y);    //cout<<d3.x<<' '<<d3.y<<endl;    double d1d2=kross(d2,d1);    if(d1d2==0) return false;    double k1=kross(d3,d2)/d1d2;    double k2=kross(d3,d1)/d1d2;    //cout<<k1<<' '<<k2<<endl;    if(k1>0&&k1<1&&k2>0)        return true;    else        return false; }int get_points(point a,point b){    int res=0;    for(int i=1;i<=n;i++)    {        if(pd(line(a,b),l[i]))            res++;    }    return res;} void build_edge(){    for(int i=0;i<n+3;i++)    {        for(int j=0;j<n+3;j++)            g[i][j]=INF;    }    for(int i=1;i<=n;i++)    {        for(int j=i+1;j<=n;j++)        {            g[i][j]=g[j][i]=get_points(l[i].s,l[j].s);        }        g[n+1][i]=g[i][n+1]=get_points(s,l[i].s);        g[n+2][i]=g[i][n+2]=get_points(t,l[i].s);    }    g[n+1][n+2]=g[n+2][n+1]=get_points(s,t);}void spfa(int start) {      queue<int> Q;      int i, now;      memset(visit, false, sizeof(visit));      for (i = 1; i <= n+2; i++){          dist[i] = INF;      }      dist[start] = 0;      Q.push(start);      visit[start] = true;      while (!Q.empty()) {          now = Q.front();          Q.pop();          visit[now] = false;          for (i = 1; i <= n+2; i++) {              if (dist[i] > dist[now] + g[now][i]) {                  dist[i] = dist[now] + g[now][i];                  if (visit[i] == 0) {                      Q.push(i);                      visit[i] = true;                  }              }          }      }  } int main(){    while(~scanf("%d",&n),n)    {        for(int i=1;i<=n;i++)        {            scanf("%lf%lf%lf%lf",&l[i].s.x,&l[i].s.y,&l[i].t.x,&l[i].t.y);        }        scanf("%lf%lf%lf%lf",&s.x,&s.y,&t.x,&t.y);        build_edge();        //cout<<pd(line(l[2].s,t),l[3])<<endl;        /*for(int i=1;i<=n+2;i++)        {            for(int j=1;j<=n+2;j++)                cout<<g[i][j]<<' ';            cout<<endl;        }*/        spfa(n+1);        printf("%d\n",dist[n+2]);    }}
原创粉丝点击