2017.7.11 图论测试


  我先用费用流的方法去跑spfa,然后完美T掉6个点。

  就说正解吧,正解是跑两次spfa,然后就可以找出最短路覆盖的边(详细过程请看代码rebuild())。然后建图跑最大流

Code

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <ctime>
  4 #include <cmath>
  5 #include <cctype>
  6 #include <cstring>
  7 #include <cstdlib>
  8 #include <fstream>
  9 #include <sstream>
 10 #include <algorithm>
 11 #include <map>
 12 #include <set>
 13 #include <stack>
 14 #include <queue>
 15 #include <vector>
 16 #include <stack>
 17 #ifndef WIN32
 18 #define Auto "%lld"
 19 #else
 20 #define Auto "%I64d"
 21 #endif
 22 using namespace std;
 23 typedef bool boolean;
 24 const signed int inf = (signed)((1u << 31) - 1);
 25 const double eps = 1e-6;
 26 const int binary_limit = 128;
 27 #define smin(a, b) a = min(a, b)
 28 #define smax(a, b) a = max(a, b)
 29 #define max3(a, b, c) max(a, max(b, c))
 30 #define min3(a, b, c) min(a, min(b, c))
 31 template<typename T>
 32 inline boolean readInteger(T& u){
 33     char x;
 34     int aFlag = 1;
 35     while(!isdigit((x = getchar())) && x != '-' && x != -1);
 36     if(x == -1) {
 37         ungetc(x, stdin);    
 38         return false;
 39     }
 40     if(x == '-'){
 41         x = getchar();
 42         aFlag = -1;
 43     }
 44     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
 45     ungetc(x, stdin);
 46     u *= aFlag;
 47     return true;
 48 }
 49 
 50 typedef class Edge {
 51     public:
 52         int end;
 53         int next;
 54         int flow;
 55         int cap;
 56         int lvl;
 57         Edge(int end = 0, int next = -1, int flow = 0, int cap = 0, int lvl = 0):end(end), next(next), flow(flow), cap(cap), lvl(lvl) {    }
 58 }Edge;
 59 
 60 typedef class MapManager {
 61     public:
 62         int ce;
 63         vector<Edge> edge;
 64         int* h;
 65         
 66         MapManager():ce(0), h(NULL) {        }
 67         MapManager(int nodes):ce(0) {
 68             h = new int[(const int)(nodes + 1)];
 69             memset(h, -1, sizeof(int) * (nodes + 1));
 70         }
 71         
 72         inline void addEdge(int from, int end, int flow, int cap, int lvl) {
 73             edge.push_back(Edge(end, h[from], flow, cap, lvl));
 74             h[from] = ce++;
 75         }
 76         
 77         inline void addDoubleEdge(int from, int end, int cap, int lvl) {
 78             if(cap == 0)    return;
 79             addEdge(from, end, 0, cap, lvl);
 80             addEdge(end, from, cap, cap, lvl);
 81         }
 82         
 83         Edge& operator [] (int pos) {
 84             return edge[pos];
 85         }
 86 }MapManager;
 87 #define m_begin(g, i) (g).h[(i)]
 88 #define m_endpos -1
 89 
 90 #define LL long long
 91 
 92 int n, m;
 93 int s, t;
 94 MapManager g;
 95 
 96 inline void init() {
 97     readInteger(n);
 98     readInteger(m);
 99     g = MapManager(n + 1);
100     s = 1, t = n;
101     for(int i = 1, a, b, c; i <= m; i++) {
102         readInteger(a);
103         readInteger(b);
104         readInteger(c);
105         g.addDoubleEdge(a, b, 1, c);
106     }
107 }
108 
109 queue<int> que;
110 boolean* vis;
111 LL *f;
112 LL *f1;
113 inline void init_spfa() {
114     vis = new boolean[t + 1];
115     f = new LL[t + 1];
116     f1 = new LL[t + 1];
117 }
118 
119 inline void spfa(int s, int t, LL* &f2, boolean sign) {
120     memset(vis, false, sizeof(boolean) * (n + 1));
121     memset(f2, 0x7f, sizeof(long long) * (n + 1));
122     f2[s] = 0;
123     que.push(s);
124     while(!que.empty()) {
125         int e = que.front();
126         que.pop();
127         vis[e] = false;
128         for(int i = m_begin(g, e); i != m_endpos; i = g[i].next) {
129             int& eu = g[i].end;
130             if(g[i].flow ^ sign)    continue;
131             if(f2[eu] > f2[e] + g[i].lvl) {
132                 f2[eu] = f2[e] + g[i].lvl;
133                 if(!vis[eu] && eu != t) {
134                     vis[eu] = true;
135                     que.push(eu);
136                 } 
137             }
138         }
139     }
140 }
141 
142 boolean* onpath;
143 MapManager rg;
144 inline void rebuild() {
145     rg = MapManager(t);
146     onpath = new boolean[(t + 1)];
147     memset(onpath, false, sizeof(boolean) * (t + 1));
148     for(int i = 1; i <= n; i++)
149         if(f[i] + f1[i] == f[t])
150             onpath[i] = true;
151     for(int i = s; i <= t; i++) {
152         if(!onpath[i])    continue;
153         for(int j = m_begin(g, i); j != m_endpos; j = g[j].next) {
154             int& e = g[j].end;
155             if(onpath[e] && g[j].flow == 0 && f[i] + g[j].lvl == f[e])
156                 rg.addDoubleEdge(i, e, 1, 0); //,printf("%d->%d\n", i, e);
157         }
158     }
159 }
160 
161 int *divs;
162 inline boolean bfs() {
163     memset(divs, -1, sizeof(int) * (t + 1));
164     que.push(s);
165     divs[s] = 0;
166     while(!que.empty()) {
167         int e = que.front();
168         que.pop();
169         for(int i = m_begin(rg, e); i != m_endpos; i = rg[i].next) {
170             int& eu = rg[i].end;
171             if(divs[eu] != -1 || rg[i].cap == rg[i].flow)    continue;
172             divs[eu] = divs[e] + 1;
173             que.push(eu);
174         }
175     }
176     return divs[t] != -1;
177 }
178 
179 int *cur;
180 int blockedflow(int node, int minf) {
181     if(node == t || minf == 0)    return minf;
182     int f, flow = 0;
183     for(int& i = cur[node]; i != m_endpos; i = rg[i].next) {
184         int& e = rg[i].end;
185         if(divs[e] == divs[node] + 1 && (f = blockedflow(e, min(minf, rg[i].cap - rg[i].flow))) > 0) {
186             rg[i].flow += f;
187             rg[i ^ 1].flow -= f;
188             flow += f;
189             minf -= f;
190             if(minf == 0)    return flow;
191         }
192     }
193     return flow;
194 }
195 
196 inline int dinic() {
197     divs = new int[(t + 1)];
198     cur = new int[(t + 1)];
199     int maxflow = 0;
200     while(bfs()) {
201         for(int i = s; i <= t; i++)
202             cur[i] = m_begin(rg, i);
203         maxflow += blockedflow(s, inf);
204     }
205     return maxflow;
206 }
207 
208 inline void solve() {
209     printf("%d", dinic());
210 }
211 
212 int main() {
213     freopen("change.in", "r", stdin);
214     freopen("change.out", "w", stdout);
215     init();
216     init_spfa();
217     spfa(s, t, f, false);
218     spfa(t, s, f1, true);
219     rebuild();
220     solve();
221     return 0;
222 }


  二分答案,然后奇、偶数分开分别连源点和汇点,两者加起来是素数就加一条边。特殊处理1,只保留一个。

Code

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <ctime>
  4 #include <cmath>
  5 #include <cctype>
  6 #include <cstring>
  7 #include <cstdlib>
  8 #include <fstream>
  9 #include <sstream>
 10 #include <algorithm>
 11 #include <map>
 12 #include <set>
 13 #include <stack>
 14 #include <queue>
 15 #include <vector>
 16 #include <stack>
 17 #ifndef WIN32
 18 #define Auto "%lld"
 19 #else
 20 #define Auto "%I64d"
 21 #endif
 22 using namespace std;
 23 typedef bool boolean;
 24 const signed int inf = (signed)((1u << 31) - 1);
 25 const double eps = 1e-6;
 26 const int binary_limit = 128;
 27 #define smin(a, b) a = min(a, b)
 28 #define smax(a, b) a = max(a, b)
 29 #define max3(a, b, c) max(a, max(b, c))
 30 #define min3(a, b, c) min(a, min(b, c))
 31 template<typename T>
 32 inline boolean readInteger(T& u){
 33     char x;
 34     int aFlag = 1;
 35     while(!isdigit((x = getchar())) && x != '-' && x != -1);
 36     if(x == -1) {
 37         ungetc(x, stdin);    
 38         return false;
 39     }
 40     if(x == '-'){
 41         x = getchar();
 42         aFlag = -1;
 43     }
 44     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
 45     ungetc(x, stdin);
 46     u *= aFlag;
 47     return true;
 48 }
 49 
 50 typedef class Edge {
 51     public:
 52         int end;
 53         int next;
 54         int flow;
 55         int cap;
 56         int lvl;
 57         Edge(int end = 0, int next = -1, int flow = 0, int cap = 0, int lvl = 0):end(end), next(next), flow(flow), cap(cap), lvl(lvl) {    }
 58 }Edge;
 59 
 60 typedef class MapManager {
 61     public:
 62         int ce;
 63         vector<Edge> edge;
 64         int* h;
 65         
 66         MapManager():ce(0), h(NULL) {        }
 67         MapManager(int nodes):ce(0) {
 68             h = new int[(const int)(nodes + 1)];
 69             memset(h, -1, sizeof(int) * (nodes + 1));
 70         }
 71         
 72         inline void addEdge(int from, int end, int flow, int cap, int lvl) {
 73             edge.push_back(Edge(end, h[from], flow, cap, lvl));
 74             h[from] = ce++;
 75         }
 76         
 77         inline void addDoubleEdge(int from, int end, int cap, int lvl) {
 78             if(cap == 0)    return;
 79 //            printf("%d -> %d (with the capt %d)\n", from, end, cap);
 80             addEdge(from, end, 0, cap, lvl);
 81             addEdge(end, from, cap, cap, lvl);
 82         }
 83         
 84         Edge& operator [] (int pos) {
 85             return edge[pos];
 86         }
 87         
 88         inline void clear() {
 89             edge.clear();
 90             delete[] h;
 91         }
 92 }MapManager;
 93 #define m_begin(g, i) (g).h[(i)]
 94 #define m_endpos -1
 95 
 96 int n, m;
 97 int s, t;
 98 int *fs, *ts, *ls;
 99 
100 inline void init() {
101     readInteger(n);
102     readInteger(m);
103     s = 0, t = n + 1;
104     fs = new int[(n + 1)];
105     ts = new int[(n + 1)];
106     ls = new int[(n + 1)];
107     int sum = 0;
108     for(int i = 1; i <= n; i++) {
109         readInteger(fs[i]);
110         readInteger(ts[i]);
111         readInteger(ls[i]);
112         sum += fs[i];
113     }
114     if(sum < m) {
115         puts("-1");
116         exit(0);
117     }
118 }
119 
120 int num = 0;
121 const int limit = 2e7;
122 int prime[1270608];
123 boolean *vis;
124 inline void Euler() {
125     vis = new boolean[limit + 1];
126     memset(vis, false, sizeof(boolean) * (limit + 1));
127     for(int i = 2; i <= limit; i++) {
128         if(!vis[i])    prime[num++] = i;
129         for(int j = 0; j < num; j++) {
130             int x = i * 1LL * prime[j];
131             if(x > limit)    break;
132             vis[x] = true;
133             if((i % prime[j]) == 0)    break;
134         }
135     }
136 }
137 
138 inline void init_map(MapManager& g, int mid, int& sum) {
139     g = MapManager(t);
140     int maxonef = 0, maxid = -1;
141     for(int i = 1; i <= n; i++)
142         if(ls[i] <= mid && ts[i] == 1 && fs[i] > maxonef)
143             maxonef = fs[i], maxid = i;
144     for(int i = 1; i <= n; i++) {
145         if(((ts[i] == 1 && i == maxid) || (ts[i] != 1 && (ts[i] & 1) == 1)) && ls[i] <= mid)
146             g.addDoubleEdge(s, i, fs[i], ls[i]), sum += fs[i];
147         else if((ts[i] & 1) == 0 && ls[i] <= mid)
148             g.addDoubleEdge(i, t, fs[i], ls[i]), sum += fs[i];
149     }
150     for(int i = 1; i <= n; i++) {
151         if(!(ts[i] & 1))    continue;
152         for(int j = 1; j <= n; j++) {
153             if(!vis[ts[i] + ts[j]]) {
154                 g.addDoubleEdge(i, j, inf, 0);
155             }
156         }
157     }
158 }
159 
160 int* dep;
161 queue<int> que;
162 MapManager g;
163 inline boolean bfs(int mid) {
164     memset(dep, -1, sizeof(int) * (t + 1));
165     dep[s] = 0;
166     que.push(s);
167     while(!que.empty()) {
168         int e = que.front();
169         que.pop();
170         for(int i = m_begin(g, e); i != m_endpos; i = g[i].next) {
171             int& eu = g[i].end;
172             if(dep[eu] != -1)    continue;
173             if(g[i].lvl > mid)    continue;
174             if(g[i].cap == g[i].flow)    continue;
175             dep[eu] = dep[e] + 1;
176             que.push(eu);
177         }
178     }
179     return dep[t] != -1;
180 }
181 
182 int* cur;
183 int blockedflow(int node, int minf, int mid) {
184     if(node == t || minf == 0)    return minf;
185 //    cout << node << endl;
186     int f, flow = 0;
187     for(int& i = cur[node]; i != m_endpos; i = g[i].next) {
188         int& e = g[i].end;
189         if(g[i].lvl <= mid && dep[e] == dep[node] + 1 && (f = blockedflow(e, min(minf, g[i].cap - g[i].flow), mid)) > 0) {
190             g[i].flow += f;
191             g[i ^ 1].flow -= f;
192             flow += f;
193             minf -= f;
194             if(minf == 0)    return flow;
195         }
196     }
197     return flow;
198 }
199 
200 inline void init_dinic() {
201     dep = new int[(t + 1)];
202     cur = new int[(t + 1)];
203 }
204 
205 int dinic(int mid) {
206     int sum = 0, maxflow = 0;
207     init_map(g, mid, sum);
208     while(bfs(mid)) {
209         for(int i = s; i <= t; i++)
210             cur[i] = m_begin(g, i);
211         maxflow += blockedflow(s, inf, mid);
212     }
213     g.clear();
214 //    cout << maxflow << endl;
215     return sum - maxflow;
216 }
217 
218 inline void solve() {
219     int l = 1, r = (1e9) + 1;
220     while(l <= r) {
221         int mid = (l + r) >> 1;
222         if(dinic(mid) >= m)    r = mid - 1;
223         else l = mid + 1;
224     }
225     if(r == (1e9) + 1)    puts("-1");
226     else printf("%d\n", r + 1);
227 }
228 
229 int main() {
230     freopen("card.in", "r", stdin);
231     freopen("card.out", "w", stdout);
232     Euler();
233     init();
234     init_dinic();
235     solve();
236     return 0;
237 }


  先Tarjan弄一发,然后开始spfa,转移的时候判一下起点和终点是否在同一强连通分量内。

Code

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <ctime>
  4 #include <cmath>
  5 #include <cctype>
  6 #include <cstring>
  7 #include <cstdlib>
  8 #include <fstream>
  9 #include <sstream>
 10 #include <algorithm>
 11 #include <map>
 12 #include <set>
 13 #include <stack>
 14 #include <queue>
 15 #include <vector>
 16 #include <stack>
 17 #ifndef WIN32
 18 #define Auto "%lld"
 19 #else
 20 #define Auto "%I64d"
 21 #endif
 22 using namespace std;
 23 typedef bool boolean;
 24 const signed int inf = (signed)((1u << 31) - 1);
 25 const signed long long llf = (signed long long)((1ull << 61) - 1);
 26 const double eps = 1e-6;
 27 const int binary_limit = 128;
 28 #define smin(a, b) a = min(a, b)
 29 #define smax(a, b) a = max(a, b)
 30 #define max3(a, b, c) max(a, max(b, c))
 31 #define min3(a, b, c) min(a, min(b, c))
 32 template<typename T>
 33 inline boolean readInteger(T& u){
 34     char x;
 35     int aFlag = 1;
 36     while(!isdigit((x = getchar())) && x != '-' && x != -1);
 37     if(x == -1) {
 38         ungetc(x, stdin);    
 39         return false;
 40     }
 41     if(x == '-'){
 42         x = getchar();
 43         aFlag = -1;
 44     }
 45     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
 46     ungetc(x, stdin);
 47     u *= aFlag;
 48     return true;
 49 }
 50 
 51 ///map template starts
 52 typedef class Edge{
 53     public:
 54         int end;
 55         int next;
 56         int w;
 57         Edge(const int end = 0, const int next = 0, const int w = 0):end(end), next(next), w(w){}
 58 }Edge;
 59 
 60 typedef class MapManager{
 61     public:
 62         int ce;
 63         int *h;
 64         Edge *edge;
 65         MapManager(){}
 66         MapManager(int points, int limit):ce(0){
 67             h = new int[(const int)(points + 1)];
 68             edge = new Edge[(const int)(limit + 1)];
 69             memset(h, 0, sizeof(int) * (points + 1));
 70         }
 71         inline void addEdge(int from, int end, int w){
 72             edge[++ce] = Edge(end, h[from], w);
 73             h[from] = ce;
 74         }
 75         inline void addDoubleEdge(int from, int end, int w){
 76             addEdge(from, end, w);
 77             addEdge(end, from, w);
 78         }
 79         Edge& operator [] (int pos) {
 80             return edge[pos];
 81         }
 82 }MapManager;
 83 #define m_begin(g, i) (g).h[(i)]
 84 ///map template ends
 85 
 86 #define LL long long
 87 
 88 typedef class Data {
 89     public:
 90         LL mag;
 91         LL dis;
 92         
 93         Data(LL mag = llf, LL dis = llf):mag(mag), dis(dis) {        }
 94 
 95         boolean operator < (Data b) const {
 96             if(mag != b.mag)    return mag < b.mag;
 97             return dis < b.dis;
 98         }
 99         
100         Data operator + (Data b) {
101             return Data(mag + b.mag, dis + b.dis);
102         }
103 }Data;
104 
105 int n, m;
106 MapManager g;
107 MapManager rg;
108 
109 inline void init() {
110     readInteger(n);
111     readInteger(m);
112     g = MapManager(n, m);
113     rg = MapManager(n, m);
114     for(int i = 1, a, b, c; i <= m; i++) {
115         readInteger(a);
116         readInteger(b);
117         readInteger(c);
118         g.addEdge(a, b, c);
119         rg.addEdge(b, a, c);
120     }
121 }
122 
123 int cnt = 0, scc = 0;
124 int* visitID;
125 int* exitID;
126 boolean* visited;
127 boolean* instack;
128 stack<int> s;
129 int *belong;
130 inline void init_tarjan() {
131     int an = n + 1;
132     visitID = new int[(an)];
133     exitID = new int[(an)];
134     visited = new boolean[(an)];
135     instack = new boolean[(an)];
136     belong = new int[(an)];
137     memset(visited, false, sizeof(boolean) * an);
138     memset(instack, false, sizeof(boolean) * an);
139     memset(belong, 0, sizeof(int) * an);
140 }
141 
142 void tarjan(int node) {
143     visitID[node] = exitID[node] = cnt++;
144     visited[node] = instack[node] = true;
145     s.push(node);
146     
147     for(int i = m_begin(g, node); i; i = g[i].next) {
148         int& e = g[i].end;
149         if(!visited[e]) {
150             tarjan(e);
151             smin(exitID[node], exitID[e]);
152         } else if(instack[e]) {
153             smin(exitID[node], visitID[e]);
154         }
155     }
156     
157     if(visitID[node] == exitID[node]) {
158         int now = -1;
159         scc++;
160         while(now != node) {
161             now = s.top();
162             s.pop();
163             instack[now] = false;
164             belong[now] = scc;
165         }
166     }
167 }
168 
169 deque<int> que;
170 Data *f;
171 boolean *vis;
172 inline void spfa(int s) {
173     f = new Data[n + 1];
174     vis = new boolean[n + 1];
175     memset(vis, false, sizeof(boolean) * (n + 1));
176     que.push_front(s);
177     f[s] = Data(0, 0);
178     while(!que.empty()) {
179         int e = que.front();
180         que.pop_front();
181         vis[e] = false;
182         for(int i = m_begin(rg, e); i; i = rg[i].next) {
183             int& eu = rg[i].end;
184             Data w((belong[e] == belong[eu]) ? (1) : (0), rg[i].w);
185             if(f[e] + w < f[eu]) {
186                 f[eu] = f[e] + w;
187                 if(!vis[eu]) {
188                     vis[eu] = true;
189                     if(!que.empty() && f[eu] < f[que.front()])
190                         que.push_front(eu);
191                     else
192                         que.push_back(eu);
193                 }
194             }
195         }
196     }
197 }
198 
199 inline void solve() {
200     for(int i = 2; i <= n; i++) {
201         if(f[i].mag == llf)
202             puts("-1");
203         else 
204             printf(Auto" "Auto"\n", f[i].mag, f[i].dis);
205     }
206 }
207 
208 int main() {
209     freopen("festival.in", "r", stdin);
210     freopen("festival.out", "w", stdout);
211     init();
212     init_tarjan();
213     for(int i = 1; i <= n; i++)
214         if(!visited[i])
215             tarjan(i);
216     spfa(1);
217     solve();
218     return 0;
219 }

 

posted @ 2017-07-12 11:12  阿波罗2003  阅读(181)  评论(0编辑  收藏  举报