poj 2135 Farm Tour

来源:互联网 发布:linux的常用命令 编辑:程序博客网 时间:2024/06/13 04:07

题目链接:点这里。

Description

When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of which contains his house and the Nth of which contains the big barn. A total M (1 <= M <= 10000) paths that connect the fields in various ways. Each path connects two different fields and has a nonzero length smaller than 35,000.To show off his farm in the best way, he walks a tour that starts at his house, potentially travels through some fields, and ends at the barn. Later, he returns (potentially through some fields) back to his house again.He wants his tour to be as short as possible, however he doesn't want to walk on any given path more than once. Calculate the shortest tour possible. FJ is sure that some tour exists for any given farm.

Input

* Line 1: Two space-separated integers: N and M.* Lines 2..M+1: Three space-separated integers that define a path: The starting field, the end field, and the path's length.

Output

A single line containing the length of the shortest tour.

Sample Input

4 51 2 12 3 13 4 11 3 22 4 2

Sample Output

6

【题意】

给你一张无向图,然后让你找一条1->n->1的路,其中每一条路都只走一次。

【分析】

费用流啊,不会啊,被虐了,总算是懂了。还算可以。首先是建图。显然无向图应该建双向边,然后每一条边既有正向边又有反向边。所以实际上一行输入建立了四条边。然后就是用spfa跑流量了,找出两条增光路,更新一下就行了。

【代码】

#include<iostream>#include<cstdio>#include<cstring>#include<string.h>#include<algorithm>#include<vector>#include<cmath>#include<stdlib.h>#include<time.h>#include<stack>#include<set>#include<map>#include<queue>#include<sstream>using namespace std;#define rep0(i,l,r) for(int i = (l);i < (r);i++)#define rep1(i,l,r) for(int i = (l);i <= (r);i++)#define rep_0(i,r,l) for(int i = (r);i > (l);i--)#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)#define MS0(a) memset(a,0,sizeof(a))#define MS_1(a) memset(a,-1,sizeof(a))#define MSinf(a) memset(a,0x3f,sizeof(a))#define MSfalse(a) memset(a,false,sizeof(a))#define pin1(a) printf("%d",(a))#define pin2(a,b) printf("%d %d",(a),(b))#define pin3(a,b,c) printf("%d %d %d",(a),(b),(c))#define pll1(a) printf("%lld",(a))#define pll2(a,b) printf("%lld %lld",(a),(b))#define pll3(a,b,c) printf("%lld %lld %lld",(a),(b),(c))#define pdo1(a) printf("%f",(a))#define pdo2(a,b) printf("%f %f",(a),(b))#define pdo3(a,b,c) printf("%f %f %f",(a),(b),(c))#define huiche puts("")#define inf 0x3f3f3f3f#define lson (ind<<1),l,mid#define rson ((ind<<1)|1),mid+1,r#define uint unsigned inttypedef pair<int,int> PII;#define A first#define B second#define pb push_back#define mp make_pair#define ll long long#define eps 1e-8#define pi acos(-1.0)inline void read1(int &num) {    char in;    bool IsN=false;    in=getchar();    while(in!='-'&&(in<'0'||in>'9')) in=getchar();    if(in=='-') {        IsN=true;        num=0;    } else num=in-'0';    while(in=getchar(),in>='0'&&in<='9') {        num*=10,num+=in-'0';    }    if(IsN) num=-num;}inline void read2(int &a,int &b) {    read1(a);    read1(b);}inline void read3(int &a,int &b,int &c) {    read1(a);    read1(b);    read1(c);}inline void read1(ll &num) {    char in;    bool IsN=false;    in=getchar();    while(in!='-'&&(in<'0'||in>'9')) in=getchar();    if(in=='-') {        IsN=true;        num=0;    } else num=in-'0';    while(in=getchar(),in>='0'&&in<='9') {        num*=10,num+=in-'0';    }    if(IsN) num=-num;}inline void read2(ll &a,ll &b) {    read1(a);    read1(b);}inline void read3(ll &a,ll &b,ll &c) {    read1(a);    read1(b);    read1(c);}inline void read1(double &num) {    char in;    double Dec=0.1;    bool IsN=false,IsD=false;    in=getchar();    while(in!='-'&&in!='.'&&(in<'0'||in>'9'))        in=getchar();    if(in=='-') {        IsN=true;        num=0;    } else if(in=='.') {        IsD=true;        num=0;    } else num=in-'0';    if(!IsD) {        while(in=getchar(),in>='0'&&in<='9') {            num*=10;            num+=in-'0';        }    }    if(in!='.') {        if(IsN) num=-num;        return ;    } else {        while(in=getchar(),in>='0'&&in<='9') {            num+=Dec*(in-'0');            Dec*=0.1;        }    }    if(IsN) num=-num;}inline void read2(double &a,double &b) {    read1(a);    read1(b);}inline void read3(double &a,double &b,double &c) {    read1(a);    read1(b);    read1(c);}///----------------------------------------------------------------------------------------------------------------#define N 1005struct Edge {    int from;//起点    int to;//终点    int flow;//剩余流量    int cost;//花费    Edge(int u,int v,int f,int co):from(u),to(v),flow(f),cost(co) {};};int n,m,s,t;vector<Edge> edges;vector<int> G[N];int inq[N];//是否在队列中int d[N];//距离int p[N];//前面一条路int a[N];//可改进量void init(int n) { //初始化    for(int i=0; i<n; i++)        G[i].clear();    edges.clear();}void addedge(int from,int to,int cap,int cost) { //加边    edges.push_back(Edge(from,to,cap,cost));    edges.push_back(Edge(to,from,0,-cost));    int m=edges.size();    G[from].push_back(m-2);//from有一条编号为m-2的路    G[to].push_back(m-1);}bool SPFA(int s,int t,int &flow,          int &cost) { //寻找最小费用的增广路,使用引用同时修改原flow,cost    for(int i=1; i<=n; i++)        d[i]=inf;//初始化所有距离都是无穷大    memset(inq,0,sizeof(inq));//队列为空    d[s]=0;    inq[s]=1;    p[s]=0;    a[s]=inf;    queue<int> Q;    Q.push(s);    while(!Q.empty()) {        int u=Q.front();        Q.pop();        inq[u]--;        for(int i=0; i<G[u].size(); i++) {            Edge& e=edges[G[u][i]];            if(e.flow>0 && d[e.to]>d[u]+e.cost) { //满足可增广且可变短                d[e.to]=d[u]+e.cost;                p[e.to]=G[u][i];                a[e.to]=min(a[u],e.flow);                if(!inq[e.to]) {                    inq[e.to]++;                    Q.push(e.to);                }            }        }    }    if(d[t]==inf) return false;//汇点不可达则退出    flow+=a[t];    cost+=d[t]*a[t];    int u=t;    while(u!=s) { //更新正向边和反向边        edges[p[u]].flow-=a[t];        edges[p[u]^1].flow+=a[t];        u=edges[p[u]].from;    }    return true;}int MincotMaxflow(int s,int t) {    int flow=0,cost=0;    SPFA(s,t,flow,cost);    SPFA(s,t,flow,cost);    return cost;}int main() {//    freopen("in.txt","r",stdin);    while(scanf("%d%d",&n,&m)!=EOF)    {        init(n+1);        int from,to,value;        rep0(i,0,m)        {            read3(from,to,value);            addedge(from,to,1,value);            addedge(to,from,1,value);        }        printf("%d\n",MincotMaxflow(1,n));    }    return 0;}
原创粉丝点击