Solution to a problem P2294 [[HNOI2005] cunning businessman]

Topic Link

Solution [HNOI2005] cunning businessman

Title effect: the m given constraints, each constraint condition indicates \ (\ sum_ ^ {S} {} T = V \) , determines whether or not solvable in FIG.

We now have to analyze the topic:

\ (\ sum_ {S} ^ {t} = v \) , this formula is harder, makes us very uncomfortable. Then we have no way to type this complex and converted into other forms of it?

The answer is yes. For this formula, we can consider the way to use the prefix and converts it to other forms

Set \ (SUM (I) = \ ^ sum_0 ia_i \) ( \ (a_i \) is the title given value profit and loss)

Then thatcancerEquation becomes \ (\ sum_ {s} ^ {t} = sum (t) - sum (s - 1) = v \)

Do you feel this formula very familiar, especially the difference between the two numbers is not to make you think of the difference constraint?

But this difference constraints and bare a little bit different, we can not directly set the board, may continue to deform

\(sum(t) - sum(s - 1) = v \iff \begin{cases}sum(t) - sum(s - 1) \leq v \\ sum(t) - sum(s - 1) \geq v\end{cases}\)

Both \ (\ leq \) there \ (\ geq \) easy to get a ride? \ (--1 \) Well.

\(\begin{cases}sum(t) - sum(s - 1) \leq v \\ sum(t) - sum(s - 1) \geq v\end{cases} \iff \begin{cases} sum(t) - sum(s-1) \leq v \\ sum(s - 1) - sum(t) \leq -v\end{cases}\)

Then this is a bare differential constraints, the board set it directly. If there are no negative loop solution . But note a few minor problems:

  • There are negative right , not invincible super mad pull cool mankind is the fastest single-source shortest path algorithm Dijkstra

  • Figure probably not connected (you should think of). The solution is simple. The original number in FIG inside point from \ (0 \) to the \ (n-\) (0 at this point from the prefix and), it is added directly to a virtual point \ (n + 1 \) , from \ (n + 1 \ ) to a weight value of each point is connected to side 0, can run SPFA

  • Do not write hung up (it seems to be nonsense Orz)

Finally, the code presented code of wind ugly

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 1280;
const int maxm = 10240 << 1;
struct Edge{
    int from,to,dist;
    Edge() = default;
    Edge(int a,int b,int c):from(a),to(b),dist(c){}
}Edges[maxm];
int head[maxn],nxt[maxm],tot,n,m;
inline void clear_edge(){
    tot = 0;
    memset(head,0,sizeof(head));
    memset(nxt,0,sizeof(nxt));
}
inline void addedge(int from,int to,int dist){
    Edges[++tot] = Edge(from,to,dist);
    nxt[tot] = head[from];
    head[from] = tot;
}//存图没啥好讲的,clear_edge和addedge望文生义吧
int dist[maxn],cnt[maxn],inq[maxn];
inline bool spfa(int s){//SPFA,用STL望巨佬们见谅。返回true代表差分约束有解,返回false代表有负环,即差分约束无解
    queue<int> Q;
    memset(cnt,0,sizeof(cnt));
    memset(inq,0,sizeof(inq));
    memset(dist,0x3f,sizeof(dist));
    dist[s] = 0;Q.push(s);inq[s] = true;
    while(!Q.empty()){
        int u = Q.front();Q.pop();
        inq[u] = false;
        for(int i = head[u];i;i = nxt[i]){
            const Edge &e = Edges[i];
            if(dist[e.from] + e.dist < dist[e.to]){
                dist[e.to] = dist[e.from] + e.dist;
                if(!inq[e.to]){
                    Q.push(e.to);
                    inq[e.to] = true;
                    if(++cnt[e.to] > n)return false;
                }
            }
        }
    }
    return true;
}
int t;
inline void solve(){//对一组数据求解
    scanf("%d %d",&n,&m);
    clear_edge();
    for(int i = 1;i <= m;i++){
        int s,t,v;
        scanf("%d %d %d",&s,&t,&v);
        addedge(s - 1,t,v);
        addedge(t,s - 1,-v);//如何连边上文已经提到了
    }
    for(int i = 0;i <= n;i++)
        addedge(n + 1,i,0);
    puts(spfa(n + 1) ? "true" : "false");
}
int main(){
    scanf("%d",&t);
    while(t--)
        solve();
    return 0;//收工
}

Guess you like

Origin www.cnblogs.com/colazcy/p/11514717.html