[SDOI2009] 晨跑 (费用流) ---链表 VS Vector

Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑、仰卧起坐等等,不过到目前为止,他坚持下来的只有晨跑。
现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交。Elaxia每天从寝室出发跑到学校,保证寝室编号为1,学校编号为N。
Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路口。Elaxia耐力不太好,他希望在一个周期内跑的路程尽量短,但是又希望训练周期包含的天数尽量长。
除了练空手道,Elaxia其他时间都花在了学习和找MM上面,所有他想请你帮忙为他设计一套满足他要求的晨跑计划。


输入
第一行2个数n,m。表示十字路口数和街道数。
接下来m行,每行3个数a,b,c,表示十字路口a和十字路口b之间有条长度为c的街道(单向)。


输出
2个数,第一个数为最长周期的天数,第二个数为满足最长天数的条件下最短的路程长度。


输入样例
7 10
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
2 5 5
3 6 6
5 7 1
6 7 1


输出样例
2 11

N<=200  M<=20000

听某大佬说过 网络流用vector一般要比链表快

于是我试了试 结果如下 

都开了O2 vector直接起飞 

直冲Rank 1 (-_-)

  1 #include<queue> 
  2 #include<cstdio>
  3 #include<iostream>
  4 #define MAXN 20010
  5 
  6 using namespace std;
  7 
  8 const int INF=0x7fffffff;
  9 const int N=210;
 10 
 11 struct JSF {
 12     int to;
 13     int next;
 14     int fee;
 15     int val;
 16 }; 
 17 
 18 JSF e[MAXN<<1];
 19 
 20 int head[MAXN<<1],tot=1;
 21 
 22 int n,m,a,b,c,src,decc,ans1,ans2;
 23 
 24 int dis[N<<1],pre[N<<1];
 25 
 26 bool vis[N<<1];
 27 
 28 queue<int> q;
 29 
 30 inline void read(int&x) {
 31     int f=1;x=0;char c=getchar();
 32     while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
 33     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();}
 34     x=x*f;
 35 }
 36 
 37 inline void add(int x,int y,int v,int f) {
 38     e[++tot].to=y;
 39     e[tot].fee=f;
 40     e[tot].val=v;
 41     e[tot].next=head[x];
 42     head[x]=tot;
 43 }
 44 
 45 inline void add_edge(int x,int y,int v,int f) {
 46     add(x,y,v,f);add(y,x,0,-f);
 47 }
 48 
 49 bool spfa() {
 50     for(int i=1;i<=n<<1;i++) dis[i]=INF,vis[i]=false,pre[i]=-1;
 51     while(!q.empty()) q.pop();
 52     q.push(src);
 53     vis[src]=true;
 54     dis[src]=0;
 55     pre[src]=0;
 56     while(!q.empty()) {
 57         int u=q.front();
 58         q.pop();
 59         vis[u]=false;
 60         for(int i=head[u];i;i=e[i].next) {
 61             int to=e[i].to;
 62             if(e[i].val&&dis[to]>dis[u]+e[i].fee) {
 63                 dis[to]=dis[u]+e[i].fee;
 64                 pre[to]=i;
 65                 if(!vis[to]) {
 66                     q.push(to);
 67                     vis[to]=true;
 68                 }
 69             }
 70         }
 71     }
 72     return dis[decc]!=INF;
 73 }
 74 
 75 inline int change() {
 76     int Flow=INF;
 77     for(int i=pre[decc];i;i=pre[e[i^1].to]) 
 78       Flow=min(Flow,e[i].val);
 79     ans1++;
 80     for(int i=pre[decc];i;i=pre[e[i^1].to]) {
 81         e[i].val-=Flow;
 82         e[i^1].val+=Flow;
 83     }
 84     return Flow*dis[decc];
 85 }
 86 
 87 inline void ISPA() {
 88     while(spfa()) 
 89       ans2+=change();
 90     return;
 91 }
 92 
 93 inline int hhh() {
 94     freopen("run.in","r",stdin);
 95     freopen("run.out","w",stdout);
 96     read(n);read(m);
 97     src=1;decc=n<<1;
 98     for(int i=1;i<=m;i++) {
 99         read(a);read(b);read(c);
100         add_edge(a+n,b,1,c);
101     }
102     for(int i=2;i<n;i++) add_edge(i,i+n,1,0);
103     add_edge(1,1+n,INF,0);
104     add_edge(n,n<<1,INF,0);
105     ISPA();
106     printf("%d %d
",ans1,ans2);
107     return 0;
108 }
109 
110 int sb=hhh();
111 int main() {;}
链表
  1 /*
  2     事实证明 vector 的确 比链表 跑得快
  3     开O2后直接起飞 
  4 */
  5 #include<queue>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<iostream>
  9 #define MAXN 20010
 10 
 11 using namespace std;
 12 
 13 const int INF=0x7fffffff;
 14 const int N=810;
 15 
 16 int n,m,a,b,c,ans1,ans2,decc,src;
 17 
 18 int dis[N<<1],pre[N<<1],f[2][N<<1][N<<1];
 19 
 20 bool vis[N<<1];
 21 
 22 vector<int> e[MAXN];
 23 
 24 queue<int> q;
 25 
 26 inline void read(int&x) {
 27     int f=1;x=0;char c=getchar();
 28     while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
 29     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();}
 30     x=x*f;
 31 }
 32 
 33 inline void add(int x,int y,int v,int fee) {
 34     e[x].push_back(y);
 35     f[0][x][y]=v;
 36     f[1][x][y]=fee;
 37 }
 38 
 39 inline void add_edge(int x,int y,int v,int f) {
 40     add(x,y,v,f);add(y,x,0,-f);
 41 }
 42 
 43 bool spfa() {
 44     for(int i=1;i<=n<<1;i++) dis[i]=INF,vis[i]=false,pre[i]=-1;
 45     while(!q.empty()) q.pop();
 46     q.push(src);
 47     dis[src]=0;
 48     vis[src]=true;
 49     pre[src]=0;
 50     while(!q.empty()) {
 51         int u=q.front();
 52         q.pop();
 53         vis[u]=false;
 54         for(int i=0;i<e[u].size();i++) {
 55             int to=e[u][i];
 56             if(f[0][u][to]&&dis[to]>dis[u]+f[1][u][to]) {
 57                 dis[to]=dis[u]+f[1][u][to];
 58                 pre[to]=u;
 59                 if(!vis[to]) {
 60                     q.push(to);
 61                     vis[to]=true;
 62                 }
 63             }
 64         }
 65     }
 66     return dis[decc]!=INF;
 67 }
 68 
 69 inline int change() {
 70     int flow=INF;ans1++;
 71     for(int i=decc;i!=1;i=pre[i])
 72       flow=min(flow,f[0][pre[i]][i]);
 73     for(int i=decc;i!=1;i=pre[i]) {
 74         f[0][pre[i]][i]-=flow;
 75         f[0][i][pre[i]]+=flow;
 76     }
 77     return flow*dis[decc];
 78 }
 79 
 80 inline void ISPA() {
 81     while(spfa())
 82       ans2+=change();
 83     return;
 84 }
 85 
 86 inline int hhh() {
 87     freopen("run.in","r",stdin);
 88     freopen("run.out","w",stdout);
 89     read(n);read(m);
 90     src=1;decc=n<<1;
 91     for(int i=1;i<=m;i++) {
 92         read(a);read(b);read(c);
 93         add_edge(a+n,b,1,c);
 94     }
 95     for(int i=2;i<n;i++) add_edge(i,i+n,1,0);
 96     add_edge(1,1+n,INF,0);
 97     add_edge(n,n<<1,INF,0);
 98     ISPA();
 99     printf("%d %d
",ans1,ans2);
100     return 0;
101 }
102 
103 int sb=hhh();
104 int main() {;}
vector


作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

 
原文地址:https://www.cnblogs.com/whistle13326/p/7341273.html