hdu 3666 THE MATRIX PROBLEM //2010哈尔滨现场赛

来源:互联网 发布:淘宝搜索什么能看片 编辑:程序博客网 时间:2024/04/24 19:11


差分约束,不是很难看出来

不过需要一下流氓剪枝。。。。

#include <cstdio>#include <cstring>#include <queue>#include <cmath>using namespace std;#define swap(t,a,b) (t=a,a=b,b=t)const int E=400000;const int V=1001;const double INF = 1e15;struct EDGE{    int link,next;    double val;} edge[E];int head[V],cnt[V],e;double dist[V];bool vis[V];void addedge(int a,int b,double c){    edge[e].link=b;    edge[e].val=c;    edge[e].next=head[a];    head[a]=e++;}int relax(int u,int v,double c){    if(dist[v]>dist[u]+c)    {        //求的是最大值,若求最小值,反号        dist[v]=dist[u]+c;        return 1;    }    return 0;}int SPFA(int src,int n){    memset(vis,false,sizeof(vis));    memset(cnt,0,sizeof(cnt));    for(int i=1; i<=n; ++i)  dist[i]=INF;    dist[src]=0;    vis[src]=true;    queue<int> q;    q.push(src);    ++cnt[src];    int t = (int) sqrt(1.0 * n);    while(!q.empty())    {        int u,v;        u=q.front();        q.pop();        vis[u]=false;        for(int i=head[u]; i!=-1; i=edge[i].next)        {            v=edge[i].link;            if(relax(u,v,edge[i].val)==1&&!vis[v])            { //如果不用relax函数,!VIS[V]的判断应该写在这                q.push(v);                vis[v]=true;                if((++cnt[v])>t) return -1;//cnt[i]为入队列次数,用来判断是否存在负权回路            }        }    }    if(dist[n]==INF) return -2;    // src与n不可达,有些题目可省!!!    return 1;//返回src到n的最短距离,根据题意不同而改变}int main(){    int n, m, l, u;    while(scanf("%d%d%d%d", &n, &m, &l, &u) != EOF)    {        e=0;        memset(head,-1,sizeof(head));        //a 1...n        for(int i = 1; i <= n; i++)        {           int x;          for(int j = 1; j <= m; j++)          {              scanf("%d", &x);              addedge(i, j + n, log(1.0 * u / x));              addedge(j + n, i, log(1.0 * x / l));          }        }        int ans = SPFA(1, n + m);        if(ans == -1 || ans == -2)  printf("NO\n");        else printf("YES\n");    }    return 0;}


原创粉丝点击