1580. Dean's Debts

http://acm.timus.ru/problem.aspx?space=1&num=1580

简单题   对于每个联通块进行搜索  必须所以连通块都可以求出解 才可以

对于某个联通块  可以设起点为 a[]+b[]*x  (0+1*x )  然后不断搜索 搜到没有搜到的

计算这个点的a[]+b[]*x  如果搜到已经搜过的 如果b[i]+b[j]等于0 则看a[i]+a[j]是否符合所给的边 不符合则无解

否则求出 x 的值 如果一个连通块中多次求得 x 的值 则每次必须一样

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<map>

#include<vector>

#include<stack>

#include<set>

#include<map>

#include<queue>

#include<algorithm>

#include<cmath>

#define LL long long

#define sint short int

//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const int N=1005;

const double ex=1e-6;

const int INF=0x3f3f3f3f;

int head[N],I;

struct node

{

    int j,next;

    int c;

}edge[N*N];

bool visited[N];

int a[N],b[N];

double c[N];

void add(int i,int j,int c)

{

    edge[I].j=j;

    edge[I].c=c;

    edge[I].next=head[i];

    head[i]=I++;

}

bool equals(double x1,double x2)

{

    if(abs(x1-x2)<ex)

    return true;

    return false;

}

bool bfs(int l)

{

    queue<int>qt;

    stack<int>st;

    a[l]=0;

    b[l]=1;

    qt.push(l);

    st.push(l);

    visited[l]=true;

    double X;

    bool flag=false;

    while(!qt.empty())

    {

        int i=qt.front();

        qt.pop();

        for(int t=head[i];t!=-1;t=edge[t].next)

        {

            int j=edge[t].j;

            if(!visited[j])

            {

                visited[j]=true;

                a[j]=edge[t].c-a[i];

                b[j]=-b[i];

                qt.push(j);

                st.push(j);

            }else

            {

                if(b[i]+b[j]==0)

                {

                    if(a[i]+a[j]!=edge[t].c)

                    {return false;}

                }else

                {

                    double tmpx=1.0*(edge[t].c-(a[i]+a[j]))/(b[i]+b[j]);

                    if(flag&&!equals(tmpx,X))

                    {return false;}

                    flag=true;X=tmpx;

                }

            }

        }

    }

    if(flag==false)

    return false;

    while(!st.empty())

    {

        int k=st.top();

        st.pop();

        c[k]=a[k]+X*b[k];

    }

    return true;

}

int main()

{

    //freopen("data.in","r",stdin);

    int n,m;

    while(cin>>n>>m)

    {

        memset(head,-1,sizeof(head));

        I=0;

        while(m--)

        {

           int l,r;

           int k;

           cin>>l>>r>>k;

           add(l,r,k);

           add(r,l,k);

        }

        memset(visited,false,sizeof(visited));

        int l;

        for(l=1;l<=n;++l)

        {

            if(!visited[l])

            {

                if(!bfs(l))

                break;

            }

        }

        if(l<=n)

        cout<<"IMPOSSIBLE"<<endl;

        else

        {

            for(int i=1;i<=n;++i)

            printf("%.2lf\n",c[i]);

        }

    }

    return 0;

}

  

 

你可能感兴趣的:(Deb)